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::milpPhase (
double *nSol,
double *iSol,
int niter,
int *nsuciter) {
40 const int depth = (model_ && (model_ -> currentNode ())) ? model_ -> currentNode () -> depth () : 0;
42 double time0 = CoinCpuTime();
50 double z = solveMILP (nSol, iSol, niter, nsuciter);
54 bool try_again =
false;
56 if (!iSol || z >= COIN_DBL_MAX/2) {
58 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: could not find IP solution\n");
61 while (!pool_ -> Set (). empty ()) {
64 pool_ -> findClosestAndReplace (iSol, iSol, problem_ -> nVars ());
69 if (tabuPool_ . find (newSol) == tabuPool_ .
end ()) {
82 int n = problem_ -> nVars ();
85 iSol =
new double [
n];
87 for (
int i=0; i<
n; i++)
88 iSol [i] = (problem_ -> Var (i) ->
isInteger ()) ?
99 bool isChecked =
false;
110 if (tabuPool_. find (checkedSol) == tabuPool_ .
end ())
116 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: found solution is tabu\n");
121 if (tabuMgt_ == FP_TABU_NONE)
break;
123 else if ((tabuMgt_ == FP_TABU_POOL) && !(pool_ -> Set (). empty ())) {
129 pool_ -> findClosestAndReplace (iSol, nSol, problem_ -> nVars ());
134 if (tabuPool_. find (newSol) == tabuPool_ .
end ())
138 if (pool_ -> Set ().empty ())
144 }
while( !pool_ -> Set ().empty() );
146 }
else if (((tabuMgt_ == FP_TABU_CUT) ||
147 ((pool_ -> Set (). empty ()) && iSol))) {
151 problem_ -> domain () -> push (problem_ -> nVars (), iSol, milp_ -> getColLower (), milp_ -> getColUpper (),
false);
152 couenneCG_ -> genRowCuts (*milp_, cs, 0, NULL);
153 problem_ -> domain () -> pop ();
155 if (cs.sizeRowCuts ()) {
157 milp_ -> applyCuts (cs);
159 if (nSep++ < nSepRounds_)
164 }
else if ((tabuMgt_ == FP_TABU_PERTURB) && iSol) {
169 *lb = milp_ -> getColLower (),
170 *ub = milp_ -> getColUpper ();
176 int startIndex = (
int) floor (CoinDrand48 () * problem_ -> nOrigVars ());
178 for (
int ii = problem_ -> nOrigVars (); ii--; lb++, ub++) {
180 if (problem_ -> Var (ii) -> Multiplicity () <= 0)
185 int i = (startIndex + ii) % problem_ -> nOrigVars ();
187 if (problem_ -> Var (i) ->
isInteger ()) {
190 rnd = CoinDrand48 (),
199 #define RND_DECR_EXPONENT .5
201 if (iSol [i] >= lb [i] + 1.) down = 1. / pow (1. + (downMoves += 1.),
RND_DECR_EXPONENT);
204 if (rnd < down) iSol [i] -= 1.;
205 else if (rnd >
up) iSol [i] += 1.;
211 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: checking IP solution for feasibility\n");
213 isChecked = problem_ -> checkNLP0 (iSol, z,
true,
232 z > problem_ -> getCutOff ())) {
234 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 ());
242 if (CoinCpuTime () > problem_ -> getMaxCpuTime ())
247 if (fixIntVariables (iSol)) {
249 nlp_ -> setInitSol (iSol);
251 if (problem_ -> Jnlst () -> ProduceOutput (J_ALL,
J_NLPHEURISTIC)) {
252 printf (
"----------------------- Solving NLP:\n");
253 problem_ -> print ();
254 printf (
"-----------------------\n");
257 status = app_ -> OptimizeTNLP (nlp_);
259 if (nlp_ -> getSolution ()) {
260 if (nSol) CoinCopyN (nlp_ -> getSolution (), problem_ -> nVars (), nSol);
261 else nSol = CoinCopyOfArray (nlp_ -> getSolution (), problem_ -> nVars ());
264 if (nlp_ -> getSolution () && (problem_ -> Jnlst () -> ProduceOutput (J_ALL,
J_NLPHEURISTIC))) {
265 printf (
"######################## NLP solution (loop through pool):\n");
266 for (
int i=0; i< problem_ -> nVars ();) {
267 printf (
"%+e ", nlp_ -> getSolution () [i]);
268 if (!(++i % 15)) printf (
"\n");
272 z = nlp_ -> getSolValue ();
274 if (z < problem_ -> getCutOff ())
276 isChecked = problem_ -> checkNLP0 (nSol, z,
true,
281 if (isChecked && (z < problem_ -> getCutOff ()))
286 while (!pool_ -> Set (). empty ()) {
289 pool_ -> findClosestAndReplace (iSol, nSol, problem_ -> nVars ());
294 if (tabuPool_ . find (newSol) == tabuPool_ .
end ()) {
308 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: IP solution is MINLP feasible\n");
345 if (z < problem_ -> getCutOff ()) {
347 problem_ -> setCutOff (objVal);
353 chg_bds [objInd].
setUpper (t_chg_bounds::CHANGED);
358 bool is_still_feas = problem_ -> btCore (chg_bds);
370 *plb = problem_ -> Lb (),
371 *pub = problem_ -> Ub (),
372 *mlb = milp_ -> getColLower (),
373 *mub = milp_ -> getColUpper ();
375 for (
int i=problem_ -> nVars (),
j=0; i--; ++
j, ++plb, ++pub) {
377 bool neglect = problem_ -> Var (
j) -> Multiplicity () <= 0;
379 if (*plb > *mlb++) milp_ -> setColLower (
j, neglect ? 0. : *plb);
380 if (*pub < *mub++) milp_ -> setColUpper (
j, neglect ? 0. : *pub);
388 problem_ -> Jnlst () -> Printf (J_WARNING,
J_NLPHEURISTIC,
"FP: IP solution NOT MINLP feasible\n");
390 if (milpCuttingPlane_ == FP_CUT_EXTERNAL ||
391 milpCuttingPlane_ == FP_CUT_POST) {
398 problem_ -> domain () -> push (milp_);
399 couenneCG_ -> genRowCuts (*milp_, cs, 0, NULL);
400 problem_ -> domain () -> pop ();
402 if (cs.sizeRowCuts ()) {
406 milp_ -> applyCuts (cs);
409 if (milpCuttingPlane_ == FP_CUT_EXTERNAL &&
410 nSep++ < nSepRounds_)
status of lower/upper bound of a variable, to be checked/modified in bound tightening ...
Class containing a solution with infeasibility evaluation.
void setUpper(ChangeStatus upper)
Class for MINLP problems with symbolic information.
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)
#define RND_DECR_EXPONENT
void printDist(CouenneProblem *p, const double *iSol, double *nSol)
bool isInteger(CouNumber x)
is this number integer?