11 #include "CbcModel.hpp"
12 #include "CoinTime.hpp"
13 #include "CoinHelperFunctions.hpp"
26 #include "scip/scip.h"
27 #include "scip/cons_linear.h"
28 #include "scip/scipdefplugins.h"
31 using namespace Ipopt;
32 using namespace Couenne;
38 int CouenneFeasPump::solution (
double &objVal,
double *newSolution) {
40 const int depth = (model_ && (model_ -> currentNode ())) ? model_ -> currentNode () -> depth () : 0;
42 double time0 = CoinCpuTime();
46 (CoinCpuTime () >= problem_ -> getMaxCpuTime ()) ||
47 ((numberSolvePerLevel_ >= 0) &&
48 (CoinDrand48 () > 1. / CoinMax
49 (1., (
double) ((CoinMax (0, depth - numberSolvePerLevel_ + 1)) *
50 (depth - numberSolvePerLevel_ + 1))))))
56 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"==================================================== FP: BEGIN\n");
57 problem_ -> Jnlst () -> Printf (J_ERROR,
J_NLPHEURISTIC,
"[FeasPump] Initializing\n");
70 problem_ -> domain () -> push (*(problem_ -> domain () -> current ()));
79 for (
int i=problem_ -> nVars (); i--;) {
80 chg_bds [i]. setLower (t_chg_bounds::CHANGED);
81 chg_bds [i]. setUpper (t_chg_bounds::CHANGED);
84 bool is_still_feas = problem_ -> btCore (chg_bds);
92 *lb = problem_ -> domain () -> lb (),
93 *ub = problem_ -> domain () -> ub (),
94 *sol = problem_ -> domain () ->
x ();
96 for (
int i=problem_ -> nVars (); i--;)
98 if (sol [i] < lb [i]) sol [i] = lb [i];
99 else if (sol [i] > ub [i]) sol [i] = ub [i];
104 nlp_ -> setInitSol (sol);
108 if ((multHessNLP_ != 0.) ||
109 (multHessMILP_ != 0.))
110 nlp_ -> getSaveOptHessian () =
true;
112 if (problem_ -> Jnlst () -> ProduceOutput (J_ALL,
J_NLPHEURISTIC)) {
113 printf (
"initial: solving NLP:---------\n");
114 problem_ -> print ();
115 printf (
"---------------------\n");
118 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: Initial NLP... "); fflush (stdout);
121 ApplicationReturnStatus status = app_ -> OptimizeTNLP (nlp_);
123 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"done\n"); fflush (stdout);
125 if (nlp_ -> getSolution () && (problem_ -> Jnlst () -> ProduceOutput (J_ALL,
J_NLPHEURISTIC))) {
126 printf (
"######################## NLP solution (init):\n");
127 for (
int i=0; i< problem_ -> nVars ();) {
128 printf (
"%+e ", nlp_ -> getSolution () [i]);
129 if (!(++i % 15)) printf (
"\n");
131 if ((problem_ -> nVars () - 1) % 5) printf (
"\n");
136 problem_ -> domain () -> pop ();
138 if ((status != Solve_Succeeded) && (status != Solved_To_Acceptable_Level))
139 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"Feasibility Pump: error in initial NLP problem\n");
141 if ((multHessNLP_ != 0.) ||
142 (multHessMILP_ != 0.))
143 nlp_ -> getSaveOptHessian () =
false;
184 objInd = problem_ -> Obj (0) -> Body () -> Index ();
200 problem_ -> domain () -> push (model_ -> solver ());
202 expression *originalObjective = problem_ -> Obj (0) -> Body ();
205 save_mDN = multDistNLP_,
206 save_mHN = multHessNLP_,
207 save_mON = multObjFNLP_,
208 save_mDM = multDistMILP_,
209 save_mHM = multHessMILP_,
210 save_mOM = multObjFMILP_;
215 multDistNLP_ *= fabs (save_mDN);
216 multHessNLP_ *= fabs (save_mHN);
217 multObjFNLP_ *= fabs (save_mON);
218 multDistMILP_ *= fabs (save_mDM);
219 multHessMILP_ *= fabs (save_mHM);
220 multObjFMILP_ *= fabs (save_mOM);
223 if (CoinCpuTime () > problem_ -> getMaxCpuTime ())
226 problem_ -> Jnlst () -> Printf (J_ERROR,
J_NLPHEURISTIC,
"[FeasPump] Iteration %d [%gs]\n", niter, CoinCpuTime() - time0);
234 double z = solveMILP (nSol, iSol, niter, &nsuciter);
238 bool try_again =
false;
240 if (!iSol || z >= COIN_DBL_MAX/2) {
242 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: could not find IP solution\n");
245 while (!pool_ -> Set (). empty ()) {
248 pool_ -> findClosestAndReplace (iSol, iSol, problem_ -> nVars ());
253 if (tabuPool_ . find (newSol) == tabuPool_ .
end ()) {
266 int n = problem_ -> nVars ();
269 iSol =
new double [
n];
271 for (
int i=0; i<
n; i++)
272 iSol [i] = (problem_ -> Var (i) ->
isInteger ()) ?
283 bool isChecked =
false;
294 if (tabuPool_. find (checkedSol) == tabuPool_ .
end ())
300 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: found solution is tabu\n");
305 if (tabuMgt_ == FP_TABU_NONE)
break;
307 else if ((tabuMgt_ == FP_TABU_POOL) && !(pool_ -> Set (). empty ())) {
313 pool_ -> findClosestAndReplace (iSol, nSol, problem_ -> nVars ());
318 if (tabuPool_. find (newSol) == tabuPool_ .
end ())
322 if (pool_ -> Set ().empty ())
328 }
while( !pool_ -> Set ().empty() );
330 }
else if (((tabuMgt_ == FP_TABU_CUT) ||
331 ((pool_ -> Set (). empty ()) && iSol))) {
335 problem_ -> domain () -> push (problem_ -> nVars (), iSol, milp_ -> getColLower (), milp_ -> getColUpper (),
false);
336 couenneCG_ -> genRowCuts (*milp_, cs, 0, NULL);
337 problem_ -> domain () -> pop ();
339 if (cs.sizeRowCuts ()) {
341 milp_ -> applyCuts (cs);
343 if (nSep++ < nSepRounds_)
348 }
else if ((tabuMgt_ == FP_TABU_PERTURB) && iSol) {
353 *lb = milp_ -> getColLower (),
354 *ub = milp_ -> getColUpper ();
360 int startIndex = (
int) floor (CoinDrand48 () * problem_ -> nOrigVars ());
362 for (
int ii = problem_ -> nOrigVars (); ii--; lb++, ub++) {
364 if (problem_ -> Var (ii) -> Multiplicity () <= 0)
369 int i = (startIndex + ii) % problem_ -> nOrigVars ();
371 if (problem_ -> Var (i) ->
isInteger ()) {
374 rnd = CoinDrand48 (),
383 #define RND_DECR_EXPONENT .5
385 if (iSol [i] >= lb [i] + 1.) down = 1. / pow (1. + (downMoves += 1.),
RND_DECR_EXPONENT);
388 if (rnd < down) iSol [i] -= 1.;
389 else if (rnd >
up) iSol [i] += 1.;
395 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: checking IP solution for feasibility\n");
397 isChecked = problem_ -> checkNLP0 (iSol, z,
true,
416 z > problem_ -> getCutOff ())) {
418 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: infeasible/non-improving (feas==%d, z=%g, cutoff=%g), looping on pool\n", isChecked, z, problem_->getCutOff ());
426 if (CoinCpuTime () > problem_ -> getMaxCpuTime ())
431 if (fixIntVariables (iSol)) {
433 nlp_ -> setInitSol (iSol);
435 if (problem_ -> Jnlst () -> ProduceOutput (J_ALL,
J_NLPHEURISTIC)) {
436 printf (
"----------------------- Solving NLP:\n");
437 problem_ -> print ();
438 printf (
"-----------------------\n");
441 status = app_ -> OptimizeTNLP (nlp_);
443 if (nlp_ -> getSolution ()) {
444 if (nSol) CoinCopyN (nlp_ -> getSolution (), problem_ -> nVars (), nSol);
445 else nSol = CoinCopyOfArray (nlp_ -> getSolution (), problem_ -> nVars ());
448 if (nlp_ -> getSolution () && (problem_ -> Jnlst () -> ProduceOutput (J_ALL,
J_NLPHEURISTIC))) {
449 printf (
"######################## NLP solution (loop through pool):\n");
450 for (
int i=0; i< problem_ -> nVars ();) {
451 printf (
"%+e ", nlp_ -> getSolution () [i]);
452 if (!(++i % 15)) printf (
"\n");
456 z = nlp_ -> getSolValue ();
458 if (z < problem_ -> getCutOff ())
460 isChecked = problem_ -> checkNLP0 (nSol, z,
true,
465 if (isChecked && (z < problem_ -> getCutOff ()))
470 while (!pool_ -> Set (). empty ()) {
473 pool_ -> findClosestAndReplace (iSol, nSol, problem_ -> nVars ());
478 if (tabuPool_ . find (newSol) == tabuPool_ .
end ()) {
492 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: IP solution is MINLP feasible\n");
529 if (z < problem_ -> getCutOff ()) {
531 problem_ -> setCutOff (objVal);
537 chg_bds [objInd].
setUpper (t_chg_bounds::CHANGED);
542 bool is_still_feas = problem_ -> btCore (chg_bds);
554 *plb = problem_ -> Lb (),
555 *pub = problem_ -> Ub (),
556 *mlb = milp_ -> getColLower (),
557 *mub = milp_ -> getColUpper ();
559 for (
int i=problem_ -> nVars (),
j=0; i--; ++
j, ++plb, ++pub) {
561 bool neglect = problem_ -> Var (
j) -> Multiplicity () <= 0;
563 if (*plb > *mlb++) milp_ -> setColLower (
j, neglect ? 0. : *plb);
564 if (*pub < *mub++) milp_ -> setColUpper (
j, neglect ? 0. : *pub);
572 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: IP solution NOT MINLP feasible\n");
574 if (milpCuttingPlane_ == FP_CUT_EXTERNAL ||
575 milpCuttingPlane_ == FP_CUT_POST) {
582 problem_ -> domain () -> push (milp_);
583 couenneCG_ -> genRowCuts (*milp_, cs, 0, NULL);
584 problem_ -> domain () -> pop ();
586 if (cs.sizeRowCuts ()) {
590 milp_ -> applyCuts (cs);
593 if (milpCuttingPlane_ == FP_CUT_EXTERNAL &&
594 nSep++ < nSepRounds_)
611 z = solveNLP (iSol, nSol);
613 if ((nSol && iSol) &&
614 (problem_ -> Jnlst () -> ProduceOutput (J_WARNING,
J_NLPHEURISTIC))) {
619 for (
int i = 0; i < problem_ -> nVars (); ++i) {
623 if (e -> Multiplicity () <= 0)
627 (fabs (iSol [i] - ceil (iSol [i] - .5)) >
COUENNE_EPS))
631 (iSol [i] - nSol [i]) *
632 (iSol [i] - nSol [i]);
635 printf (
"FP: after NLP, distance %g, %d nonintegers\n", sqrt (dist), nNonint);
638 if (problem_ -> Jnlst () -> ProduceOutput (J_WARNING,
J_NLPHEURISTIC)) {
644 if (z > COIN_DBL_MAX/2)
653 isChecked = problem_->checkNLP0 (nSol, z,
true,
659 if (nSol && isChecked) {
661 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: NLP solution is MINLP feasible\n");
666 #ifdef FM_TRACE_OPTSOL // - if ----------------------------
668 problem_->getRecordBestSol()->update();
670 problem_->getRecordBestSol()->update(nSol, problem_->nVars(), z, problem_->getFeasTol());
672 best = problem_->getRecordBestSol()->getSol();
673 objVal = problem_->getRecordBestSol()->getVal();
674 #else // - else --------------------------
676 best = problem_->getRecordBestSol()->getModSol(problem_ -> nVars ());
681 #endif // - endif -------------------------
683 if (z < problem_ -> getCutOff ()) {
685 problem_ -> setCutOff (objVal);
692 chg_bds [objInd].
setUpper (t_chg_bounds::CHANGED);
696 bool is_still_feas = problem_ -> btCore (chg_bds);
711 }
while ((niter++ < maxIter_) &&
714 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: out of the FP loop (feas=%d\n)", retval);
725 nlp_ -> setObjective (originalObjective);
729 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: fix integer variables and rerun NLP\n");
734 problem_ -> domain () -> push (*(problem_ -> domain () -> current ()));
740 if (fixIntVariables (best)) {
742 nlp_ -> setInitSol (best);
749 status = app_ -> OptimizeTNLP (nlp_);
753 if ((status != Solve_Succeeded) &&
754 (status != Solved_To_Acceptable_Level))
757 "Feasibility Pump: error in final NLP problem (due to fixing integer variables?)\n");
759 if (nlp_ -> getSolution () && (problem_ -> Jnlst () -> ProduceOutput (J_ALL,
J_NLPHEURISTIC))) {
760 printf (
"######################## NLP solution (post):\n");
761 for (
int i=0; i< problem_ -> nVars ();) {
762 printf (
"%+e ", nlp_ -> getSolution () [i]);
763 if (!(++i % 15)) printf (
"\n");
769 double z = nlp_ -> getSolValue ();
772 bool isChecked =
false;
776 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: found nlp solution, check it\n");
778 isChecked = problem_ -> checkNLP0 (nSol, z,
true,
786 (z < problem_ -> getCutOff ())) {
788 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: feasible solution is improving\n");
790 #ifdef FM_TRACE_OPTSOL
793 problem_->getRecordBestSol()->update();
795 problem_->getRecordBestSol()->update(nSol, problem_->nVars(), z, problem_->getFeasTol());
797 best = problem_->getRecordBestSol()->getSol();
798 objVal = problem_->getRecordBestSol()->getVal();
802 best = problem_->getRecordBestSol()->getModSol(problem_ -> nVars ());
809 problem_ -> setCutOff (objVal);
813 problem_ -> domain () -> pop ();
815 if (problem_ -> Jnlst () -> ProduceOutput (J_WARNING,
J_NLPHEURISTIC)) {
816 printf (
"FP: returning MINLP feasible solution:\n");
820 CoinCopyN (best, problem_ -> nVars (), newSolution);
825 multDistNLP_ = save_mDN * fadeMult_;
826 multHessNLP_ = save_mHN * fadeMult_;
827 multObjFNLP_ = save_mON * fadeMult_;
828 multDistMILP_ = save_mDM * fadeMult_;
829 multHessMILP_ = save_mHM * fadeMult_;
830 multObjFMILP_ = save_mOM * fadeMult_;
832 if (iSol)
delete [] iSol;
833 if (nSol)
delete [] nSol;
836 problem_ -> domain () -> pop ();
844 milp_ = postlp_ = NULL;
846 problem_ -> Jnlst () -> Printf
850 problem_ -> Jnlst () -> Printf
853 if (retval && (-2 == nCalls_)) {
854 problem_ -> bonBase () -> options () -> SetNumericValue (
"time_limit", 0.001,
"couenne.");
871 p -> domain () -> push (n, v, NULL, NULL);
873 norm = infI = infN = 0.;
884 for (std::vector <exprVar *>::iterator i = p ->
Variables (). begin ();
888 if ((*i) -> Multiplicity () <= 0)
896 double inf = CoinMax (vval - floor (vval +
COUENNE_EPS),
905 if ((*i) -> Type () ==
AUX) {
909 fval = (*((*i) -> Image ())) ();
911 if ((*i) -> sign () != expression::AUX_GEQ) diff = CoinMax (diff, vval - fval);
912 else if ((*i) -> sign () != expression::AUX_LEQ) diff = CoinMax (diff, fval - vval);
921 p -> domain () -> pop ();
928 int nInfII = -1, nInfNI = -1, nInfIN = -1, nInfNN = -1;
932 normI = -1., normN = -1.,
933 infII = -1., infNI = -1.,
934 infIN = -1., infNN = -1.;
936 if (iSol)
compDistSingle (p, p -> nVars (), iSol, normI, nInfII, nInfNI, infII, infNI);
937 if (nSol)
compDistSingle (p, p -> nVars (), nSol, normN, nInfIN, nInfNN, infIN, infNN);
943 for (
int i = p -> nVars (); i--;) {
945 if (p -> Var (i) -> Multiplicity () <= 0)
949 (iSol [i] - nSol [i]) *
950 (iSol [i] - nSol [i]);
957 printf (
"IP norm i:%e n:%e dist %e #inf i:%4d n:%4d max inf i:%e n:%e ", normI, normN, dist, nInfII, nInfNI, infII, infNI);
958 printf (
"NL #inf i:%4d n:%4d max inf i:%e n:%e\n", nInfIN, nInfNN, infIN, infNN);
966 int n = p -> nVars ();
968 printf (
"i:%p n:%p\nFP # ",
969 (
void *) iSol, (
void *) nSol);
976 direction < 0 ?
'<' :
977 direction > 0 ?
'>' :
'-';
979 for (
int i=0; i<
n; i++) {
981 if (p -> Var (i) -> Multiplicity () <= 0)
984 if (i && !(i %
WRAP))
988 iS = iSol ? iSol [i] : 12345.,
989 nS = nSol ? nSol [i] : 54321.;
991 printf (
"[%4d %+e -%c- %+e (%e)] ",
993 (iSol && nSol) ? fabs (iS - nS) : 0.);
1003 distance = sqrt (distance);
1004 printf (
"\n### distance: %e\n", distance);
static Bigint * diff(Bigint *a, Bigint *b)
status of lower/upper bound of a variable, to be checked/modified in bound tightening ...
#define RND_DECR_EXPONENT
Class containing a solution with infeasibility evaluation.
void fint fint fint real fint real real real real real real real real real * e
void setUpper(ChangeStatus upper)
Class for MINLP problems with symbolic information.
void compDistSingle(CouenneProblem *p, int n, const double *v, double &norm, int &nInfI, int &nInfN, double &infI, double &infN)
void printCmpSol(CouenneProblem *p, const double *iSol, double *nSol, int direction)
double CouNumber
main number type in Couenne
const Ipopt::EJournalCategory J_NLPHEURISTIC(Ipopt::J_USER5)
Class for handling NLPs using CouenneProblem.
double distance(const double *p1, const double *p2, int size, double k=2.)
compute Euclidean distance between two points (most likely LP solutions) l_2 norm by default...
The in-memory representation of the variables element.
void printDist(CouenneProblem *p, const double *iSol, double *nSol)
void fint fint fint real fint real * x
bool isInteger(CouNumber x)
is this number integer?