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