00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "CbcModel.hpp"
00013 #include "CoinTime.hpp"
00014 #include "CoinHelperFunctions.hpp"
00015
00016 #include "CouenneExprAux.hpp"
00017 #include "CouenneFeasPump.hpp"
00018 #include "CouenneProblem.hpp"
00019 #include "CouenneProblemElem.hpp"
00020 #include "CouenneCutGenerator.hpp"
00021 #include "CouenneTNLP.hpp"
00022 #include "CouenneFPpool.hpp"
00023 #include "CouenneRecordBestSol.hpp"
00024
00025 #ifdef COIN_HAS_SCIP
00026
00027 #include "scip/scip.h"
00028 #include "scip/cons_linear.h"
00029 #include "scip/scipdefplugins.h"
00030 #endif
00031
00032 using namespace Ipopt;
00033 using namespace Couenne;
00034
00035 void printDist (CouenneProblem *p, const double *iSol, double *nSol);
00036 void printCmpSol (CouenneProblem *p, const double *iSol, double *nSol, int direction);
00037
00038
00039 int CouenneFeasPump::solution (double &objVal, double *newSolution) {
00040
00041 const int depth = (model_ && (model_ -> currentNode ())) ? model_ -> currentNode () -> depth () : 0;
00042
00043 double time0 = CoinCpuTime();
00044
00045 match_ = NULL;
00046
00047 if ((nCalls_ == 0) ||
00048
00049 (CoinCpuTime () >= problem_ -> getMaxCpuTime ()) ||
00050 ((numberSolvePerLevel_ >= 0) &&
00051 (CoinDrand48 () > 1. / CoinMax
00052 (1., (double) ((CoinMax (0, depth - numberSolvePerLevel_ + 1)) *
00053 (depth - numberSolvePerLevel_ + 1))))))
00054 return 0;
00055
00056 if (nCalls_ > 0)
00057 --nCalls_;
00058
00059 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "==================================================== FP: BEGIN\n");
00060 problem_ -> Jnlst () -> Printf (J_ERROR, J_NLPHEURISTIC, "[FeasPump] Initializing\n");
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 if (!nlp_)
00071 nlp_ = new CouenneTNLP (problem_);
00072
00073
00074 problem_ -> domain () -> push (model_ -> solver ());
00075
00076
00077
00078
00079
00080
00081
00082 t_chg_bounds *chg_bds = new t_chg_bounds [problem_ -> nVars ()];
00083
00084 for (int i=problem_ -> nVars (); i--;) {
00085 chg_bds [i]. setLower (t_chg_bounds::CHANGED);
00086 chg_bds [i]. setUpper (t_chg_bounds::CHANGED);
00087 }
00088
00089 bool is_still_feas = problem_ -> btCore (chg_bds);
00090
00091 delete [] chg_bds;
00092
00093
00094
00095
00096 double
00097 *lb = problem_ -> domain () -> lb (),
00098 *ub = problem_ -> domain () -> ub (),
00099 *sol = problem_ -> domain () -> x ();
00100
00101 for (int i=problem_ -> nVars (); i--;)
00102
00103 if (sol [i] < lb [i]) sol [i] = lb [i];
00104 else if (sol [i] > ub [i]) sol [i] = ub [i];
00105
00106
00107
00108
00109 nlp_ -> setInitSol (sol);
00110
00112
00113 if ((multHessNLP_ != 0.) ||
00114 (multHessMILP_ != 0.))
00115 nlp_ -> getSaveOptHessian () = true;
00116
00117 if (problem_ -> Jnlst () -> ProduceOutput (J_ALL, J_NLPHEURISTIC)) {
00118 printf ("initial: solving NLP:---------\n");
00119 problem_ -> print ();
00120 printf ("---------------------\n");
00121 }
00122
00123 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: Initial NLP... "); fflush (stdout);
00124
00125
00126 ApplicationReturnStatus status = app_ -> OptimizeTNLP (nlp_);
00127
00128
00129 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "done\n"); fflush (stdout);
00130
00131 if (nlp_ -> getSolution () && (problem_ -> Jnlst () -> ProduceOutput (J_ALL, J_NLPHEURISTIC))) {
00132 printf ("######################## NLP solution (init):\n");
00133 for (int i=0; i< problem_ -> nVars ();) {
00134 printf ("%+e ", nlp_ -> getSolution () [i]);
00135 if (!(++i % 15)) printf ("\n");
00136 }
00137 if ((problem_ -> nVars () - 1) % 5) printf ("\n");
00138 }
00139
00141
00142
00143
00144 if ((status != Solve_Succeeded) && (status != Solved_To_Acceptable_Level))
00145 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "Feasibility Pump: error in initial NLP problem\n");
00146
00147 if ((multHessNLP_ != 0.) ||
00148 (multHessMILP_ != 0.))
00149 nlp_ -> getSaveOptHessian () = false;
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 CouNumber
00181 *nSol = NULL,
00182 *iSol = NULL,
00183 *best = NULL;
00184
00185 int
00186 niter = 0,
00187 nsuciter = 0,
00188 retval = 0,
00189 nSep = 0,
00190 objInd = problem_ -> Obj (0) -> Body () -> Index ();
00191
00192 if (nlp_ -> getSolution ())
00193 nSol = CoinCopyOfArray (nlp_ -> getSolution (), problem_ -> nVars ());
00194
00195 bool isNlpFeas = problem_ -> checkNLP0 (nSol,
00196 nSol [objInd],
00197 true,
00198 false,
00199 true,
00200 true);
00201
00203
00204
00205
00206
00207
00208
00209
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 expression *originalObjective = problem_ -> Obj (0) -> Body ();
00221
00222 double
00223 save_mDN = multDistNLP_,
00224 save_mHN = multHessNLP_,
00225 save_mON = multObjFNLP_,
00226 save_mDM = multDistMILP_,
00227 save_mHM = multHessMILP_,
00228 save_mOM = multObjFMILP_;
00229
00230 if (!isNlpFeas) do {
00231
00232 if (CoinCpuTime () > problem_ -> getMaxCpuTime ())
00233 break;
00234
00235 if (niter) {
00236 multDistNLP_ *= fabs (save_mDN);
00237 multHessNLP_ *= fabs (save_mHN);
00238 multObjFNLP_ *= fabs (save_mON);
00239 multDistMILP_ *= fabs (save_mDM);
00240 multHessMILP_ *= fabs (save_mHM);
00241 multObjFMILP_ *= fabs (save_mOM);
00242 }
00243
00244 problem_ -> Jnlst () -> Printf (J_ERROR, J_NLPHEURISTIC, "[FeasPump] Iteration %d [%gs]\n", niter, CoinCpuTime() - time0);
00245
00246
00247
00248
00249
00250
00251
00252 bool bad_IP_sol = false;
00253
00254 double z = solveMILP (nSol, iSol, niter, &nsuciter);
00255
00256 #if 0
00257 if (milp_ && milp_ -> getColLower ()) {
00258 printf ("fixed in milp_: ");
00259 for (int i=0; i<problem_ -> nVars (); ++i)
00260 if (fabs (milp_ -> getColUpper () [i] -
00261 milp_ -> getColLower () [i]) < COUENNE_EPS)
00262 printf ("%d ", i);
00263 }
00264
00265 problem_ -> domain () -> push (model_ -> solver ());
00266 printf ("\nfixed in model_: ");
00267 for (int i=0; i<problem_ -> nVars (); ++i)
00268 if (fabs (problem_ -> Ub (i) - problem_ -> Lb (i)) < COUENNE_EPS)
00269 printf ("%d ", i);
00270 problem_ -> domain () -> pop ();
00271
00272 problem_ -> domain () -> push (*(problem_ -> domain () -> current ()));
00273 printf ("\nfixed in problem_: ");
00274 for (int i=0; i<problem_ -> nVars (); ++i)
00275 if (fabs (problem_ -> Ub (i) - problem_ -> Lb (i)) < COUENNE_EPS)
00276 printf ("%d ", i);
00277 problem_ -> domain () -> pop ();
00278 printf ("\n");
00279 #endif
00280
00281
00282
00283 bool try_again = false;
00284
00285 if (!iSol || z >= COIN_DBL_MAX/2) {
00286
00287 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: could not find IP solution\n");
00288
00289
00290 while (!pool_ -> Set (). empty ()) {
00291
00292
00293 pool_ -> findClosestAndReplace (iSol, iSol, problem_ -> nVars ());
00294
00295 CouenneFPsolution newSol (problem_, iSol);
00296
00297
00298 if (tabuPool_ . find (newSol) == tabuPool_ . end ()) {
00299
00300
00301
00302 try_again = true;
00303 break;
00304 }
00305 }
00306
00307 if (!try_again) {
00308
00309 bad_IP_sol = true;
00310
00311
00312
00313
00314
00315 int n = problem_ -> nVars ();
00316
00317 if (!iSol)
00318 iSol = new double [n];
00319
00320 for (int i=0; i<n; i++)
00321 iSol [i] = (problem_ -> Var (i) -> isInteger ()) ?
00322 COUENNE_round (nSol [i]) :
00323 nSol [i];
00324 }
00325
00326
00327
00328
00329
00330 }
00331
00332 bool isChecked = false;
00333
00334
00335
00336
00337
00338
00339
00340
00341 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: %d solutions in pool, %d in tabu list\n", pool_ -> Set (). size (), tabuPool_ . size ());
00342
00343 CouenneFPsolution checkedSol (problem_, iSol, false);
00344
00345 if (tabuPool_. find (checkedSol) == tabuPool_ . end ())
00346
00347 tabuPool_. insert (CouenneFPsolution (problem_, iSol));
00348
00349 else {
00350
00351 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: found solution is tabu\n");
00352
00353
00354
00355
00356 if (tabuMgt_ == FP_TABU_NONE) break;
00357
00358 else if ((tabuMgt_ == FP_TABU_POOL) && !(pool_ -> Set (). empty ())) {
00359
00360
00361
00362 do {
00363
00364
00365 pool_ -> findClosestAndReplace (iSol, nSol, problem_ -> nVars ());
00366
00367 CouenneFPsolution newSol (problem_, iSol);
00368
00369
00370 if (tabuPool_. find (newSol) == tabuPool_ . end ()) {
00371
00372 tabuPool_ . insert (newSol);
00373 break;
00374 }
00375
00376
00377 if (pool_ -> Set ().empty ())
00378 {
00379 int n = problem_ -> nVars ();
00380
00381 if (!iSol)
00382 iSol = new double [n];
00383
00384 for (int i=0; i<n; i++)
00385 iSol [i] = (problem_ -> Var (i) -> isInteger ()) ?
00386 COUENNE_round (nSol [i]) :
00387 nSol [i];
00388
00389
00390
00391 }
00392
00393 } while( !pool_ -> Set ().empty() );
00394
00395 } else if (((tabuMgt_ == FP_TABU_CUT) ||
00396 ((pool_ -> Set (). empty ()) && iSol))) {
00397
00398 OsiCuts cs;
00399
00400 problem_ -> domain () -> push (problem_ -> nVars (), iSol, milp_ -> getColLower (), milp_ -> getColUpper (), false);
00401 couenneCG_ -> genRowCuts (*milp_, cs, 0, NULL);
00402 problem_ -> domain () -> pop ();
00403
00404 if (cs.sizeRowCuts ()) {
00405
00406 milp_ -> applyCuts (cs);
00407
00408 if (nSep++ < nSepRounds_)
00409 continue;
00410
00411 } else break;
00412
00413 } else if ((tabuMgt_ == FP_TABU_PERTURB) && iSol) {
00414
00415
00416
00417 const CouNumber
00418 *lb = milp_ -> getColLower (),
00419 *ub = milp_ -> getColUpper ();
00420
00421 double
00422 downMoves = 0.,
00423 upMoves = 0.;
00424
00425 int startIndex = (int) floor (CoinDrand48 () * problem_ -> nOrigVars ());
00426
00427 for (int ii = problem_ -> nOrigVars (); ii--; lb++, ub++) {
00428
00429 if (problem_ -> Var (ii) -> Multiplicity () <= 0)
00430 continue;
00431
00432
00433
00434 int i = (startIndex + ii) % problem_ -> nOrigVars ();
00435
00436 if (problem_ -> Var (i) -> isInteger ()) {
00437
00438 double
00439 rnd = CoinDrand48 (),
00440 down = 0.,
00441 up = 1.;
00442
00443
00444
00445
00446
00447
00448 #define RND_DECR_EXPONENT .5
00449
00450 if (iSol [i] >= lb [i] + 1.) down = 1. / pow (1. + (downMoves += 1.), RND_DECR_EXPONENT);
00451 if (iSol [i] <= ub [i] - 1.) up = 1. - 1. / pow (1. + (upMoves += 1.), RND_DECR_EXPONENT);
00452
00453 if (rnd < down) iSol [i] -= 1.;
00454 else if (rnd > up) iSol [i] += 1.;
00455 }
00456 }
00457 }
00458 }
00459
00460 if (!iSol)
00461 break;
00462
00463 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: checking IP solution for feasibility\n");
00464
00465 isChecked = problem_ -> checkNLP0 (iSol, z, true,
00466 false,
00467 true,
00468 true);
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 if ((!isChecked ||
00484 z > problem_ -> getCutOff ())) {
00485
00486 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 ());
00487
00488 bool try_again;
00489
00490 do {
00491
00492 try_again = false;
00493
00494 if (CoinCpuTime () > problem_ -> getMaxCpuTime ())
00495 break;
00496
00497
00498
00499 if (fixIntVariables (iSol)) {
00500
00501 nlp_ -> setInitSol (iSol);
00502
00503 if (problem_ -> Jnlst () -> ProduceOutput (J_ALL, J_NLPHEURISTIC)) {
00504 printf ("----------------------- Solving NLP:\n");
00505 problem_ -> print ();
00506 printf ("-----------------------\n");
00507 }
00508
00509 status = app_ -> OptimizeTNLP (nlp_);
00510
00511 if (nlp_ -> getSolution ()) {
00512 if (nSol) CoinCopyN (nlp_ -> getSolution (), problem_ -> nVars (), nSol);
00513 else nSol = CoinCopyOfArray (nlp_ -> getSolution (), problem_ -> nVars ());
00514 }
00515
00516 if (nlp_ -> getSolution () && (problem_ -> Jnlst () -> ProduceOutput (J_ALL, J_NLPHEURISTIC))) {
00517 printf ("######################## NLP solution (loop through pool):\n");
00518 for (int i=0; i< problem_ -> nVars ();) {
00519 printf ("%+e ", nlp_ -> getSolution () [i]);
00520 if (!(++i % 15)) printf ("\n");
00521 }
00522 }
00523
00524 z = nlp_ -> getSolValue ();
00525
00526 if (z < problem_ -> getCutOff ())
00527
00528 isChecked = problem_ -> checkNLP0 (nSol, z, true,
00529 false,
00530 true,
00531 true);
00532
00533 if (isChecked && (z < problem_ -> getCutOff ()))
00534 break;
00535 }
00536
00537
00538
00539
00540
00541 if (bad_IP_sol)
00542 while (!pool_ -> Set (). empty ()) {
00543
00544
00545 pool_ -> findClosestAndReplace (iSol, nSol, problem_ -> nVars ());
00546
00547 CouenneFPsolution newSol (problem_, iSol);
00548
00549
00550 if (tabuPool_ . find (newSol) == tabuPool_ . end ()) {
00551
00552 tabuPool_ . insert (newSol);
00553 try_again = true;
00554 break;
00555 }
00556 }
00557
00558 } while (try_again);
00559 }
00560
00561
00562
00563
00564 if (isChecked) {
00565
00566 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: IP solution is MINLP feasible\n");
00567
00568
00569
00570 retval = 1;
00571 objVal = z;
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 best = iSol;
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603 if (z < problem_ -> getCutOff ()) {
00604
00605 problem_ -> setCutOff (objVal);
00606
00607 t_chg_bounds *chg_bds = NULL;
00608
00609 if (objInd >= 0) {
00610 chg_bds = new t_chg_bounds [problem_ -> nVars ()];
00611 chg_bds [objInd].setUpper (t_chg_bounds::CHANGED);
00612 }
00613
00614
00615
00616 bool is_still_feas = problem_ -> btCore (chg_bds);
00617
00618 if (chg_bds)
00619 delete [] chg_bds;
00620
00621
00622
00623 if (!is_still_feas)
00624 break;
00625
00626
00627 const CouNumber
00628 *plb = problem_ -> Lb (),
00629 *pub = problem_ -> Ub (),
00630 *mlb = milp_ -> getColLower (),
00631 *mub = milp_ -> getColUpper ();
00632
00633 for (int i=problem_ -> nVars (), j=0; i--; ++j, ++plb, ++pub) {
00634
00635 bool neglect = problem_ -> Var (j) -> Multiplicity () <= 0;
00636
00637
00638 if (*plb > *mlb++) milp_ -> setColLower (j, neglect ? 0. : *plb);
00639 if (*pub < *mub++) milp_ -> setColUpper (j, neglect ? 0. : *pub);
00640 }
00641 }
00642
00643 break;
00644
00645 } else {
00646
00647 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: IP solution NOT MINLP feasible\n");
00648
00649 if (milpCuttingPlane_ == FP_CUT_EXTERNAL ||
00650 milpCuttingPlane_ == FP_CUT_POST) {
00651
00652
00653
00654
00655 OsiCuts cs;
00656
00657 problem_ -> domain () -> push (milp_);
00658 couenneCG_ -> genRowCuts (*milp_, cs, 0, NULL);
00659 problem_ -> domain () -> pop ();
00660
00661 if (cs.sizeRowCuts ()) {
00662
00663
00664
00665 milp_ -> applyCuts (cs);
00666
00667
00668 if (milpCuttingPlane_ == FP_CUT_EXTERNAL &&
00669 nSep++ < nSepRounds_)
00670 continue;
00671 }
00672 }
00673 }
00674
00675
00676
00677
00678
00679 nSep = 0;
00680
00681
00682
00683
00684
00685
00686 z = solveNLP (iSol, nSol);
00687
00688 if ((nSol && iSol) &&
00689 (problem_ -> Jnlst () -> ProduceOutput (J_WARNING, J_NLPHEURISTIC))) {
00690
00691 double dist = 0.;
00692 int nNonint = 0;
00693
00694 for (int i = 0; i < problem_ -> nVars (); ++i) {
00695
00696 exprVar *e = problem_ -> Var (i);
00697
00698 if (e -> Multiplicity () <= 0)
00699 continue;
00700
00701 if (e -> isInteger () &&
00702 (fabs (iSol [i] - ceil (iSol [i] - .5)) > COUENNE_EPS))
00703 ++nNonint;
00704
00705 dist +=
00706 (iSol [i] - nSol [i]) *
00707 (iSol [i] - nSol [i]);
00708 }
00709
00710 printf ("FP: after NLP, distance %g, %d nonintegers\n", sqrt (dist), nNonint);
00711 }
00712
00713 if (problem_ -> Jnlst () -> ProduceOutput (J_WARNING, J_NLPHEURISTIC)) {
00714
00715 printDist (problem_, iSol, nSol);
00716 printCmpSol (problem_, iSol, nSol, 0);
00717 }
00718
00719 if (z > COIN_DBL_MAX/2)
00720 break;
00721
00722
00723
00724 isChecked = false;
00725
00726 if (nSol) {
00727
00728 isChecked = problem_->checkNLP0 (nSol, z, true,
00729 false,
00730 true,
00731 true);
00732 }
00733
00734 if (nSol && isChecked) {
00735
00736 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: NLP solution is MINLP feasible\n");
00737
00738 retval = 1;
00739 objVal = z;
00740
00741 #ifdef FM_TRACE_OPTSOL // - if ----------------------------
00742 #ifdef FM_CHECKNLP2
00743 problem_->getRecordBestSol()->update();
00744 #else
00745 problem_->getRecordBestSol()->update(nSol, problem_->nVars(), z, problem_->getFeasTol());
00746 #endif
00747 best = problem_->getRecordBestSol()->getSol();
00748 objVal = problem_->getRecordBestSol()->getVal();
00749 #else // - else --------------------------
00750 #ifdef FM_CHECKNLP2
00751 best = problem_->getRecordBestSol()->getModSol(problem_ -> nVars ());
00752 #else
00753 best = nSol;
00754 #endif
00755 objVal = z;
00756 #endif // - endif -------------------------
00757
00758 if (z < problem_ -> getCutOff ()) {
00759
00760 problem_ -> setCutOff (objVal);
00761
00762 t_chg_bounds *chg_bds = NULL;
00763
00764 if (objInd >= 0) {
00765
00766 chg_bds = new t_chg_bounds [problem_ -> nVars ()];
00767 chg_bds [objInd].setUpper (t_chg_bounds::CHANGED);
00768 }
00769
00770
00771 bool is_still_feas = problem_ -> btCore (chg_bds);
00772
00773 if (chg_bds)
00774 delete [] chg_bds;
00775
00776 if (!is_still_feas)
00777 break;
00778 }
00779 }
00780
00781
00782
00783
00784
00785
00786 } while ((niter++ < maxIter_) &&
00787 (retval == 0));
00788
00789 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: out of the FP loop (feas=%d\n)", retval);
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799 if (nlp_)
00800 nlp_ -> setObjective (originalObjective);
00801
00802 if (retval > 0) {
00803
00804 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: fix integer variables and rerun NLP\n");
00805
00806 if (!nlp_)
00807 nlp_ = new CouenneTNLP (problem_);
00808
00809 problem_ -> domain () -> push (*(problem_ -> domain () -> current ()));
00810
00811
00812
00813
00814
00815 if (fixIntVariables (best)) {
00816
00817 nlp_ -> setInitSol (best);
00818
00820
00821
00822
00823
00824 status = app_ -> OptimizeTNLP (nlp_);
00825
00827
00828 if ((status != Solve_Succeeded) &&
00829 (status != Solved_To_Acceptable_Level))
00830
00831 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC,
00832 "Feasibility Pump: error in final NLP problem (due to fixing integer variables?)\n");
00833
00834 if (nlp_ -> getSolution () && (problem_ -> Jnlst () -> ProduceOutput (J_ALL, J_NLPHEURISTIC))) {
00835 printf ("######################## NLP solution (post):\n");
00836 for (int i=0; i< problem_ -> nVars ();) {
00837 printf ("%+e ", nlp_ -> getSolution () [i]);
00838 if (!(++i % 15)) printf ("\n");
00839 }
00840 }
00841
00842
00843
00844 double z = nlp_ -> getSolValue ();
00845
00846
00847 bool isChecked = false;
00848
00849 if (nSol) {
00850
00851 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: found nlp solution, check it\n");
00852
00853 isChecked = problem_ -> checkNLP0 (nSol, z, true,
00854 false,
00855 true,
00856 true);
00857 }
00858
00859 if (nSol &&
00860 isChecked &&
00861 (z < problem_ -> getCutOff ())) {
00862
00863 problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: feasible solution is improving\n");
00864
00865 #ifdef FM_TRACE_OPTSOL
00866
00867 #ifdef FM_CHECKNLP2
00868 problem_->getRecordBestSol()->update();
00869 #else
00870 problem_->getRecordBestSol()->update(nSol, problem_->nVars(), z, problem_->getFeasTol());
00871 #endif
00872 best = problem_->getRecordBestSol()->getSol();
00873 objVal = problem_->getRecordBestSol()->getVal();
00874 #else
00875
00876 #ifdef FM_CHECKNLP2
00877 best = problem_->getRecordBestSol()->getModSol(problem_ -> nVars ());
00878 #else
00879 best = nSol;
00880 #endif
00881 objVal = z;
00882 #endif
00883
00884 problem_ -> setCutOff (objVal);
00885 }
00886 }
00887
00888 problem_ -> domain () -> pop ();
00889
00890 if (problem_ -> Jnlst () -> ProduceOutput (J_WARNING, J_NLPHEURISTIC)) {
00891 printf ("FP: returning MINLP feasible solution:\n");
00892 printDist (problem_, best, nSol);
00893 }
00894
00895 CoinCopyN (best, problem_ -> nVars (), newSolution);
00896 }
00897
00898
00899
00900 multDistNLP_ = save_mDN * fadeMult_;
00901 multHessNLP_ = save_mHN * fadeMult_;
00902 multObjFNLP_ = save_mON * fadeMult_;
00903 multDistMILP_ = save_mDM * fadeMult_;
00904 multHessMILP_ = save_mHM * fadeMult_;
00905 multObjFMILP_ = save_mOM * fadeMult_;
00906
00907 if (iSol) delete [] iSol;
00908 if (nSol) delete [] nSol;
00909
00910
00911 problem_ -> domain () -> pop ();
00912
00913
00914
00915
00916
00917 delete milp_;
00918 delete postlp_;
00919 milp_ = postlp_ = NULL;
00920
00921 if (match_) {
00922 delete [] match_;
00923 match_ = NULL;
00924 }
00925
00926 problem_ -> Jnlst () -> Printf
00927 (J_WARNING, J_NLPHEURISTIC, "FP: done ===================\n");
00928
00929 if (!retval)
00930 problem_ -> Jnlst () -> Printf
00931 (J_ERROR, J_NLPHEURISTIC, "FP: No solution found\n");
00932
00933 if (retval && (-2 == nCalls_)) {
00934 problem_ -> bonBase () -> options () -> SetNumericValue ("time_limit", 0.001, "couenne.");
00935 problem_ -> bonBase () -> setDoubleParameter (Bonmin::BabSetupBase::MaxTime, 0.001);
00936 }
00937
00938 return retval;
00939 }
00940
00941
00942 void compDistSingle (CouenneProblem *p,
00943 int n,
00944 const double *v,
00945 double &norm,
00946 int &nInfI,
00947 int &nInfN,
00948 double &infI,
00949 double &infN) {
00950
00951 p -> domain () -> push (n, v, NULL, NULL);
00952
00953 norm = infI = infN = 0.;
00954 nInfI = nInfN = 0;
00955
00956 while (n--) {
00957 norm += (*v * *v);
00958 ++v;
00959 }
00960 v -= n;
00961
00962 norm = sqrt (norm);
00963
00964 for (std::vector <exprVar *>::iterator i = p -> Variables (). begin ();
00965 i != p -> Variables (). end ();
00966 ++i) {
00967
00968 if ((*i) -> Multiplicity () <= 0)
00969 continue;
00970
00971 CouNumber
00972 vval = (**i) ();
00973
00974 if ((*i) -> isInteger ()) {
00975
00976 double inf = CoinMax (vval - floor (vval + COUENNE_EPS),
00977 ceil (vval - COUENNE_EPS) - vval);
00978
00979 if (inf > COUENNE_EPS) {
00980 ++nInfI;
00981 infI += inf;
00982 }
00983 }
00984
00985 if ((*i) -> Type () == AUX) {
00986
00987 double
00988 diff = 0.,
00989 fval = (*((*i) -> Image ())) ();
00990
00991 if ((*i) -> sign () != expression::AUX_GEQ) diff = CoinMax (diff, vval - fval);
00992 else if ((*i) -> sign () != expression::AUX_LEQ) diff = CoinMax (diff, fval - vval);
00993
00994 if (diff > COUENNE_EPS) {
00995 ++nInfN;
00996 infN += diff;
00997 }
00998 }
00999 }
01000
01001 p -> domain () -> pop ();
01002 }
01003
01004
01005
01006 void printDist (CouenneProblem *p, const double *iSol, double *nSol) {
01007
01008 int nInfII = -1, nInfNI = -1, nInfIN = -1, nInfNN = -1;
01009
01010 double
01011 dist = -1.,
01012 normI = -1., normN = -1.,
01013 infII = -1., infNI = -1.,
01014 infIN = -1., infNN = -1.;
01015
01016 if (iSol) compDistSingle (p, p -> nVars (), iSol, normI, nInfII, nInfNI, infII, infNI);
01017 if (nSol) compDistSingle (p, p -> nVars (), nSol, normN, nInfIN, nInfNN, infIN, infNN);
01018
01019 if (iSol && nSol) {
01020
01021 dist = 0.;
01022
01023 for (int i = p -> nVars (); i--;) {
01024
01025 if (p -> Var (i) -> Multiplicity () <= 0)
01026 continue;
01027
01028 dist +=
01029 (iSol [i] - nSol [i]) *
01030 (iSol [i] - nSol [i]);
01031 }
01032
01033 dist = sqrt (dist);
01034 }
01035
01036 printf ("FP: ");
01037 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);
01038 printf ("NL #inf i:%4d n:%4d max inf i:%e n:%e\n", nInfIN, nInfNN, infIN, infNN);
01039 }
01040
01041
01042 #define WRAP 3
01043
01044 void printCmpSol (CouenneProblem *p, const double *iSol, double *nSol, int direction) {
01045
01046 int n = p -> nVars ();
01047
01048 printf ("i:%p n:%p\nFP # ",
01049 (void *) iSol, (void *) nSol);
01050
01051 double
01052 distance = 0.,
01053 diff;
01054
01055 char c =
01056 direction < 0 ? '<' :
01057 direction > 0 ? '>' : '-';
01058
01059 for (int i=0; i<n; i++) {
01060
01061 if (p -> Var (i) -> Multiplicity () <= 0)
01062 continue;
01063
01064 if (i && !(i % WRAP))
01065 printf ("\nFP # ");
01066
01067 double
01068 iS = iSol ? iSol [i] : 12345.,
01069 nS = nSol ? nSol [i] : 54321.;
01070
01071 printf ("[%4d %+e -%c- %+e (%e)] ",
01072 i, iS, c, nS,
01073 (iSol && nSol) ? fabs (iS - nS) : 0.);
01074
01075 if (iSol && nSol) {
01076 diff = iS - nS;
01077 distance += (diff*diff);
01078 }
01079 }
01080
01081 if (iSol && nSol) {
01082
01083 distance = sqrt (distance);
01084 printf ("\n### distance: %e\n", distance);
01085 }
01086 }