00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CbcModel.hpp"
00012 #include "CoinTime.hpp"
00013 #include "CoinHelperFunctions.hpp"
00014
00015 #include "CouenneExprAux.hpp"
00016 #include "CouenneFeasPump.hpp"
00017 #include "CouenneProblem.hpp"
00018 #include "CouenneProblemElem.hpp"
00019 #include "CouenneCutGenerator.hpp"
00020 #include "CouenneTNLP.hpp"
00021 #include "CouenneFPpool.hpp"
00022 #include "CouenneRecordBestSol.hpp"
00023
00024 #ifdef COIN_HAS_SCIP
00025
00026 #include "scip/scip.h"
00027 #include "scip/cons_linear.h"
00028 #include "scip/scipdefplugins.h"
00029 #endif
00030
00031 using namespace Ipopt;
00032 using namespace Couenne;
00033
00034 void printDist (CouenneProblem *p, const double *iSol, double *nSol);
00035 void printCmpSol (CouenneProblem *p, const double *iSol, double *nSol, int direction);
00036
00037
00038 int CouenneFeasPump::milpPhase (double *nSol, double *iSol, int niter, int *nsuciter) {
00039
00040 const int depth = (model_ && (model_ -> currentNode ())) ? model_ -> currentNode () -> depth () : 0;
00041
00042 double time0 = CoinCpuTime();
00043
00044
00045
00046
00047
00048
00049
00050 double z = solveMILP (nSol, iSol, niter, nsuciter);
00051
00052
00053
00054 bool try_again = false;
00055
00056 if (!iSol || z >= COIN_DBL_MAX/2) {
00057
00058 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: could not find IP solution\n");
00059
00060
00061 while (!pool_ -> Set (). empty ()) {
00062
00063
00064 pool_ -> findClosestAndReplace (iSol, iSol, problem_ -> nVars ());
00065
00066 CouenneFPsolution newSol (problem_, iSol);
00067
00068
00069 if (tabuPool_ . find (newSol) == tabuPool_ . end ()) {
00070
00071 try_again = true;
00072 break;
00073 }
00074 }
00075
00076 if (!try_again) {
00077
00078
00079
00080
00081
00082 int n = problem_ -> nVars ();
00083
00084 if (!iSol)
00085 iSol = new double [n];
00086
00087 for (int i=0; i<n; i++)
00088 iSol [i] = (problem_ -> Var (i) -> isInteger ()) ?
00089 COUENNE_round (nSol [i]) :
00090 nSol [i];
00091 }
00092
00093
00094
00095
00096
00097 }
00098
00099 bool isChecked = false;
00100
00101
00102
00103
00104
00105
00106
00107
00108 CouenneFPsolution checkedSol (problem_, iSol, false);
00109
00110 if (tabuPool_. find (checkedSol) == tabuPool_ . end ())
00111
00112 tabuPool_. insert (CouenneFPsolution (problem_, iSol));
00113
00114 else {
00115
00116 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: found solution is tabu\n");
00117
00118
00119
00120
00121 if (tabuMgt_ == FP_TABU_NONE) break;
00122
00123 else if ((tabuMgt_ == FP_TABU_POOL) && !(pool_ -> Set (). empty ())) {
00124
00125
00126 do {
00127
00128
00129 pool_ -> findClosestAndReplace (iSol, nSol, problem_ -> nVars ());
00130
00131 CouenneFPsolution newSol (problem_, iSol);
00132
00133
00134 if (tabuPool_. find (newSol) == tabuPool_ . end ())
00135 break;
00136
00137
00138 if (pool_ -> Set ().empty ())
00139 {
00140 delete[] iSol;
00141 iSol = NULL;
00142 }
00143
00144 } while( !pool_ -> Set ().empty() );
00145
00146 } else if (((tabuMgt_ == FP_TABU_CUT) ||
00147 ((pool_ -> Set (). empty ()) && iSol))) {
00148
00149 OsiCuts cs;
00150
00151 problem_ -> domain () -> push (problem_ -> nVars (), iSol, milp_ -> getColLower (), milp_ -> getColUpper (), false);
00152 couenneCG_ -> genRowCuts (*milp_, cs, 0, NULL);
00153 problem_ -> domain () -> pop ();
00154
00155 if (cs.sizeRowCuts ()) {
00156
00157 milp_ -> applyCuts (cs);
00158
00159 if (nSep++ < nSepRounds_)
00160 continue;
00161
00162 } else break;
00163
00164 } else if ((tabuMgt_ == FP_TABU_PERTURB) && iSol) {
00165
00166
00167
00168 const CouNumber
00169 *lb = milp_ -> getColLower (),
00170 *ub = milp_ -> getColUpper ();
00171
00172 double
00173 downMoves = 0.,
00174 upMoves = 0.;
00175
00176 int startIndex = (int) floor (CoinDrand48 () * problem_ -> nOrigVars ());
00177
00178 for (int ii = problem_ -> nOrigVars (); ii--; lb++, ub++) {
00179
00180 if (problem_ -> Var (ii) -> Multiplicity () <= 0)
00181 continue;
00182
00183
00184
00185 int i = (startIndex + ii) % problem_ -> nOrigVars ();
00186
00187 if (problem_ -> Var (i) -> isInteger ()) {
00188
00189 double
00190 rnd = CoinDrand48 (),
00191 down = 0.,
00192 up = 1.;
00193
00194
00195
00196
00197
00198
00199 #define RND_DECR_EXPONENT .5
00200
00201 if (iSol [i] >= lb [i] + 1.) down = 1. / pow (1. + (downMoves += 1.), RND_DECR_EXPONENT);
00202 if (iSol [i] <= ub [i] - 1.) up = 1. - 1. / pow (1. + (upMoves += 1.), RND_DECR_EXPONENT);
00203
00204 if (rnd < down) iSol [i] -= 1.;
00205 else if (rnd > up) iSol [i] += 1.;
00206 }
00207 }
00208 }
00209 }
00210
00211 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: checking IP solution for feasibility\n");
00212
00213 isChecked = problem_ -> checkNLP0 (iSol, z, true,
00214 false,
00215 true,
00216 true);
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 if ((!isChecked ||
00232 z > problem_ -> getCutOff ())) {
00233
00234 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 ());
00235
00236 bool try_again;
00237
00238 do {
00239
00240 try_again = false;
00241
00242 if (CoinCpuTime () > problem_ -> getMaxCpuTime ())
00243 break;
00244
00245
00246
00247 if (fixIntVariables (iSol)) {
00248
00249 nlp_ -> setInitSol (iSol);
00250
00251 if (problem_ -> Jnlst () -> ProduceOutput (J_ALL, J_NLPHEURISTIC)) {
00252 printf ("----------------------- Solving NLP:\n");
00253 problem_ -> print ();
00254 printf ("-----------------------\n");
00255 }
00256
00257 status = app_ -> OptimizeTNLP (nlp_);
00258
00259 if (nlp_ -> getSolution ()) {
00260 if (nSol) CoinCopyN (nlp_ -> getSolution (), problem_ -> nVars (), nSol);
00261 else nSol = CoinCopyOfArray (nlp_ -> getSolution (), problem_ -> nVars ());
00262 }
00263
00264 if (nlp_ -> getSolution () && (problem_ -> Jnlst () -> ProduceOutput (J_ALL, J_NLPHEURISTIC))) {
00265 printf ("######################## NLP solution (loop through pool):\n");
00266 for (int i=0; i< problem_ -> nVars ();) {
00267 printf ("%+e ", nlp_ -> getSolution () [i]);
00268 if (!(++i % 15)) printf ("\n");
00269 }
00270 }
00271
00272 z = nlp_ -> getSolValue ();
00273
00274 if (z < problem_ -> getCutOff ())
00275
00276 isChecked = problem_ -> checkNLP0 (nSol, z, true,
00277 false,
00278 true,
00279 true);
00280
00281 if (isChecked && (z < problem_ -> getCutOff ()))
00282 break;
00283 }
00284
00285
00286 while (!pool_ -> Set (). empty ()) {
00287
00288
00289 pool_ -> findClosestAndReplace (iSol, nSol, problem_ -> nVars ());
00290
00291 CouenneFPsolution newSol (problem_, iSol);
00292
00293
00294 if (tabuPool_ . find (newSol) == tabuPool_ . end ()) {
00295 try_again = true;
00296 break;
00297 }
00298 }
00299
00300 } while (try_again);
00301 }
00302
00303
00304
00305
00306 if (isChecked) {
00307
00308 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: IP solution is MINLP feasible\n");
00309
00310
00311
00312 retval = 1;
00313 objVal = z;
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 best = iSol;
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 if (z < problem_ -> getCutOff ()) {
00346
00347 problem_ -> setCutOff (objVal);
00348
00349 t_chg_bounds *chg_bds = NULL;
00350
00351 if (objInd >= 0) {
00352 chg_bds = new t_chg_bounds [problem_ -> nVars ()];
00353 chg_bds [objInd].setUpper (t_chg_bounds::CHANGED);
00354 }
00355
00356
00357
00358 bool is_still_feas = problem_ -> btCore (chg_bds);
00359
00360 if (chg_bds)
00361 delete [] chg_bds;
00362
00363
00364
00365 if (!is_still_feas)
00366 break;
00367
00368
00369 const CouNumber
00370 *plb = problem_ -> Lb (),
00371 *pub = problem_ -> Ub (),
00372 *mlb = milp_ -> getColLower (),
00373 *mub = milp_ -> getColUpper ();
00374
00375 for (int i=problem_ -> nVars (), j=0; i--; ++j, ++plb, ++pub) {
00376
00377 bool neglect = problem_ -> Var (j) -> Multiplicity () <= 0;
00378
00379 if (*plb > *mlb++) milp_ -> setColLower (j, neglect ? 0. : *plb);
00380 if (*pub < *mub++) milp_ -> setColUpper (j, neglect ? 0. : *pub);
00381 }
00382 }
00383
00384 break;
00385
00386 } else {
00387
00388 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: IP solution NOT MINLP feasible\n");
00389
00390 if (milpCuttingPlane_ == FP_CUT_EXTERNAL ||
00391 milpCuttingPlane_ == FP_CUT_POST) {
00392
00393
00394
00395
00396 OsiCuts cs;
00397
00398 problem_ -> domain () -> push (milp_);
00399 couenneCG_ -> genRowCuts (*milp_, cs, 0, NULL);
00400 problem_ -> domain () -> pop ();
00401
00402 if (cs.sizeRowCuts ()) {
00403
00404
00405
00406 milp_ -> applyCuts (cs);
00407
00408
00409 if (milpCuttingPlane_ == FP_CUT_EXTERNAL &&
00410 nSep++ < nSepRounds_)
00411 continue;
00412 }
00413 }
00414 }
00415 }