00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CouenneProblem.hpp"
00012 #include "CouenneProblemElem.hpp"
00013 #include "CouenneExprVar.hpp"
00014 #include "CoinHelperFunctions.hpp"
00015 #include "CoinFinite.hpp"
00016
00017 #include "CouenneRecordBestSol.hpp"
00018
00019
00020
00021 using namespace Couenne;
00022
00023
00024 bool CouenneProblem::checkNLP (const double *solution, double &obj, bool recompute) const {
00025
00026 if (Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_PROBLEM)) {
00027
00028 printf ("Checking solution: %.12e (", obj);
00029
00030 for (int i=0; i<nOrigVars_ - ndefined_; i++)
00031 printf ("%g ", solution [i]);
00032 printf (")\n");
00033 }
00034
00035
00036
00037 for (register int i=0; i < nOrigVars_ - ndefined_; i++) {
00038
00039 if (variables_ [i] -> Multiplicity () <= 0)
00040 continue;
00041
00042 CouNumber val = solution [i];
00043
00044
00045
00046 exprVar *v = variables_ [i];
00047
00048 if ((v -> Type () == VAR) &&
00049 (v -> isDefinedInteger ()) &&
00050 (v -> Multiplicity () > 0) &&
00051 (fabs (val - COUENNE_round (val)) > feas_tolerance_)) {
00052
00053 Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00054 "checkNLP: integrality %d violated: %.6f [%g,%g]\n",
00055 i, val, domain_.lb (i), domain_.ub (i));
00056
00057 Jnlst () -> Printf (Ipopt::J_ALL, J_PROBLEM, "Done: (0)\n");
00058
00059 return false;
00060 }
00061 }
00062
00063 const int infeasible = 1;
00064 const int wrong_obj = 2;
00065
00066
00067
00068 CouNumber *sol = new CouNumber [nVars ()];
00069 CoinZeroN (sol + nOrigVars_ - ndefined_, nVars() - (nOrigVars_ - ndefined_));
00070 CoinCopyN (solution, nOrigVars_ - ndefined_, sol);
00071 getAuxs (sol);
00072 CoinCopyN (solution, nOrigVars_ - ndefined_, sol);
00073
00074
00075 domain_.push (nVars (), sol, domain_.lb (), domain_.ub (), false);
00076
00077 if (Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_PROBLEM)) {
00078 printf (" checkNLP: %d vars -------------------\n ", domain_.current () -> Dimension ());
00079 for (int i=0; i<domain_.current () -> Dimension (); i++) {
00080 if (i && !(i%5)) printf ("\n ");
00081 printf ("%4d %16g [%16e %16e] ", i, domain_.x (i), domain_.lb (i), domain_.ub (i));
00082 }
00083 }
00084
00085 expression *objBody = Obj (0) -> Body ();
00086
00087
00088
00089
00090
00091
00092 CouNumber realobj = obj;
00093
00094 if (objBody)
00095 realobj =
00096 (objBody -> Index () >= 0) ?
00097 sol [objBody -> Index ()] :
00098 (*(objBody -> Image () ? objBody -> Image () : objBody)) ();
00099
00100 Jnlst () -> Printf (Ipopt::J_ALL, J_PROBLEM, " Objective: %.12e %.12e %.12e\n",
00101 realobj, objBody -> Index () >= 0 ? sol [objBody -> Index ()] : objBody -> Value (),
00102 (*(objBody -> Image () ? objBody -> Image () : objBody)) ());
00103
00104 bool retval = true;
00105
00106 try {
00107
00108
00109
00110 if (fabs (realobj - obj) / (1. + fabs (realobj)) > feas_tolerance_) {
00111
00112 Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00113 " checkNLP, false objective: computed %g != %g xQ (diff. %g)\n",
00114 realobj, obj, realobj - obj);
00115
00116 if (!recompute)
00117 throw wrong_obj;
00118 }
00119
00120 if (recompute)
00121 obj = realobj;
00122
00123 if (Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_PROBLEM))
00124 printf (" recomputed: %.12e\n", obj);
00125
00126 for (int i=0; i < nOrigVars_ - ndefined_; i++) {
00127
00128 if (variables_ [i] -> Multiplicity () <= 0)
00129 continue;
00130
00131 CouNumber val = domain_.x (i);
00132
00133
00134
00135 if ((val > domain_.ub (i) + feas_tolerance_) ||
00136 (val < domain_.lb (i) - feas_tolerance_)) {
00137
00138 Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00139 " checkNLP: variable %d out of bounds: %.6f [%g,%g] (diff %g)\n",
00140 i, val, domain_.lb (i), domain_.ub (i),
00141 CoinMax (fabs (val - domain_.lb (i)),
00142 fabs (val - domain_.ub (i))));
00143 throw infeasible;
00144 }
00145
00146
00147
00148 if (variables_ [i] -> isDefinedInteger () &&
00149 (fabs (val - COUENNE_round (val)) > feas_tolerance_)) {
00150
00151 Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00152 " checkNLP: integrality %d violated: %.6f [%g,%g]\n",
00153 i, val, domain_.lb (i), domain_.ub (i));
00154
00155 throw infeasible;
00156 }
00157 }
00158
00159
00160
00161 for (int i=0; i < nVars (); i++) {
00162
00163 exprVar *v = variables_ [i];
00164
00165 if ((v -> Type () != AUX) ||
00166 (v -> Multiplicity () <= 0))
00167 continue;
00168
00169 if (Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_PROBLEM)) {
00170 printf (" "); v -> print ();
00171 CouNumber
00172 val = (*(v)) (),
00173 img = (*(v -> Image ())) (),
00174 diff = fabs (val - img);
00175 printf (": val = %15g; img = %-15g ", val, img);
00176 if (diff > 1e-9)
00177 printf ("[diff %12e] ", diff);
00178
00179 v -> Image () -> print ();
00180 printf ("\n");
00181 }
00182
00183
00184
00185
00186
00187 double
00188 vval = (*v) (),
00189 fval = (*(v -> Image ())) (),
00190 denom = CoinMax (1., v -> Image () -> gradientNorm (X ()));
00191
00192
00193 if (CoinIsnan (fval)) {
00194 fval = vval + 1.;
00195 denom = 1.;
00196 }
00197
00198 if (fabs (fval) > COUENNE_INFINITY)
00199 fval = COUENNE_INFINITY;
00200
00201 double
00202 delta =
00203 ((v -> sign () == expression::AUX_GEQ) && (vval >= fval)) ? 0. :
00204 ((v -> sign () == expression::AUX_LEQ) && (vval <= fval)) ? 0. : fabs (vval - fval),
00205
00206 ratio = (CoinMax (1., fabs (vval)) /
00207 CoinMax (1., fabs (fval)));
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 if ((delta > 0.) &&
00218 (((ratio > 2.) ||
00219 (ratio < .5)) ||
00220 ((delta /= denom) > CoinMin (COUENNE_EPS, feas_tolerance_)))) {
00221
00222 Jnlst () -> Printf (Ipopt::J_MOREVECTOR, J_PROBLEM,
00223 " checkNLP: auxiliary %d violates tolerance %g by %g/%g = %g\n",
00224 i, CoinMin (COUENNE_EPS, feas_tolerance_), delta*denom, denom, delta);
00225
00226 throw infeasible;
00227 }
00228 }
00229
00230
00231
00232 for (int i=0; i < nCons (); i++) {
00233
00234 CouenneConstraint *c = Con (i);
00235
00236 CouNumber
00237 body = (*(c -> Body ())) (),
00238 lhs = (*(c -> Lb ())) (),
00239 rhs = (*(c -> Ub ())) ();
00240
00241 if (((rhs < COUENNE_INFINITY) && (body > rhs + feas_tolerance_ * (1. + CoinMax (fabs (body), fabs (rhs))))) ||
00242 ((lhs > -COUENNE_INFINITY) && (body < lhs - feas_tolerance_ * (1. + CoinMax (fabs (body), fabs (lhs)))))) {
00243
00244 if (Jnlst () -> ProduceOutput (Ipopt::J_MOREVECTOR, J_PROBLEM)) {
00245
00246 printf (" checkNLP: constraint %d violated (lhs=%+e body=%+e rhs=%+e, violation %g): ",
00247 i, lhs, body, rhs, CoinMax (lhs-body, body-rhs));
00248
00249 c -> print ();
00250 }
00251
00252 throw infeasible;
00253 }
00254 }
00255 }
00256
00257 catch (int exception) {
00258
00259 switch (exception) {
00260
00261 case wrong_obj:
00262 retval = false;
00263 break;
00264
00265 case infeasible:
00266 default:
00267 retval = false;
00268 break;
00269 }
00270 }
00271
00272 delete [] sol;
00273 domain_.pop ();
00274
00275 Jnlst () -> Printf (Ipopt::J_ALL, J_PROBLEM, "Done: %d\n", retval);
00276
00277 return retval;
00278 }
00279
00280
00281
00282 double CouenneProblem::checkObj(const CouNumber *sol, const double &precision)
00283 const {
00284
00285 expression *objBody = Obj(0)->Body();
00286
00287
00288
00289
00290
00291
00292 CouNumber realObj = 0;
00293
00294 if (objBody) {
00295 realObj =
00296 (objBody ->Index() >= 0) ?
00297 sol[objBody->Index()] :
00298 (*(objBody->Image() ? objBody->Image() : objBody)) ();
00299
00300 if (
00301 #ifdef FM_TRACE_NLP
00302 (0) ||
00303 #endif
00304 (Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_PROBLEM))) {
00305 printf ("%.12e %.12e %.12e ------------------------------\n",
00306 realObj, sol[objBody -> Index ()],
00307 (*(objBody -> Image () ? objBody -> Image () : objBody)) ());
00308 }
00309 }
00310 else {
00311 printf("### ERROR: CouenneProblem::checkObj(): no objective body\n");
00312 exit(1);
00313 }
00314 return realObj;
00315 }
00316
00317
00318
00319
00320 bool CouenneProblem::checkInt(const CouNumber *sol,
00321 const int from, const int upto,
00322 const std::vector<int> listInt,
00323 const bool origVarOnly,
00324 const bool stopAtFirstViol,
00325 const double precision, double &maxViol) const {
00326
00327 bool isFeas = true;
00328
00329 for(unsigned int i=0; i<listInt.size(); i++) {
00330
00331 int ind = listInt[i];
00332
00333 if((ind < from) || (variables_ [ind] -> Multiplicity () <= 0)) {
00334 continue;
00335 }
00336
00337 if(ind >= upto) {
00338 break;
00339 }
00340
00341 CouNumber val = sol[ind];
00342 exprVar *v = variables_ [ind];
00343
00344 if ((!origVarOnly) || (v -> Type () == VAR)) {
00345
00346 double viol = fabs (val - COUENNE_round (val));
00347 maxViol = (viol > maxViol ? viol : maxViol);
00348 if(viol > precision) {
00349
00350 Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00351 "checkInt(): integrality %d violated: %.6f [%g,%g]: integer distance %e > %e (by %e)\n",
00352 i, val, domain_.lb (i), domain_.ub (i),
00353 fabs (val - COUENNE_round (val)), feas_tolerance_,
00354 fabs (val - COUENNE_round (val)) - feas_tolerance_);
00355
00356 #ifdef FM_TRACE_NLP
00357 printf("CouenneProblem::checkInt(): integrality %d violated: %.6f [%g,%g]\n",
00358 ind, val, domain_.lb (ind), domain_.ub (ind));
00359
00360 #endif
00361
00362 isFeas = false;
00363 if(stopAtFirstViol) {
00364 break;
00365 }
00366 }
00367 }
00368 }
00369 return(isFeas);
00370 }
00371
00372
00373
00374 bool CouenneProblem::checkBounds(const CouNumber *sol,
00375 const bool stopAtFirstViol,
00376 const double precision, double &maxViol) const {
00377
00378 bool isFeas = true;
00379 for(int i=0; i<nOrigVars_ - ndefined_; i++) {
00380
00381 if (variables_[i]-> Multiplicity () <= 0)
00382 continue;
00383
00384 CouNumber val = domain_.x (i);
00385 double viol = 0;
00386 double violUb = val - domain_.ub (i);
00387 double violLb = domain_.lb (i) - val;
00388
00389 viol = (viol < violUb ? violUb : viol);
00390 viol = (viol < violLb ? violLb : viol);
00391
00392 maxViol = (maxViol > viol ? maxViol : viol);
00393
00394 if (viol > precision) {
00395
00396 Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00397 "checkBounds(): variable %d out of bounds: %.6f [%g,%g] (diff %g)\n",
00398 i, val, domain_.lb (i), domain_.ub (i),
00399 CoinMax (fabs (val - domain_.lb (i)),
00400 fabs (val - domain_.ub (i))));
00401
00402 #ifdef FM_TRACE_NLP
00403 printf("CouenneProblem::checkBounds: variable %d out of bounds: %.6f [%g,%g] (diff %g)\n",
00404 i, val, domain_.lb (i), domain_.ub (i),
00405 CoinMax (fabs (val - domain_.lb (i)),
00406 fabs (val - domain_.ub (i))));
00407 #endif
00408
00409 isFeas = false;
00410 if(stopAtFirstViol) {
00411 break;
00412 }
00413 }
00414 }
00415 return isFeas;
00416 }
00417
00418
00419
00420 bool CouenneProblem::checkAux(const CouNumber *sol,
00421 const bool stopAtFirstViol,
00422 const double precision, double &maxViol) const {
00423
00424 bool isFeas = true;
00425 for (int i=0; i<nVars(); i++) {
00426
00427 exprVar *v = variables_ [i];
00428
00429 if ((v -> Type () != AUX) ||
00430 (v -> Multiplicity () <= 0))
00431 continue;
00432
00433 if (
00434 #ifdef FM_TRACE_NLP
00435 (1) ||
00436 #endif
00437
00438 (Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_PROBLEM))) {
00439 printf ("checking aux ");
00440 variables_ [i] -> print (); printf (" := ");
00441 variables_ [i] -> Image () -> print ();
00442 printf (" --- %.12e", (*(variables_ [i])) ());
00443 printf("%.12e", (*(variables_ [i] -> Image ())) ());
00444 printf (" --- %.12e = %.12e [%.12e]; {",
00445 (*(variables_ [i])) (),
00446 (*(variables_ [i] -> Image ())) (),
00447 (*(variables_ [i])) () -
00448 (*(variables_ [i] -> Image ())) ());
00449 printf ("}\n");
00450 }
00451
00452 double
00453 vval = (*v) (),
00454 fval = (*(v -> Image ())) (),
00455 denom = CoinMax (1., v -> Image () -> gradientNorm (X ()));
00456
00457
00458 if (CoinIsnan (fval)) {
00459 fval = vval + 1.;
00460 denom = 1.;
00461 }
00462
00463 if (fabs (fval) > COUENNE_INFINITY)
00464 fval = COUENNE_INFINITY;
00465
00466
00467 double
00468 delta =
00469 ((v -> sign () == expression::AUX_GEQ) && (vval >= fval)) ? 0. :
00470 ((v -> sign () == expression::AUX_LEQ) && (vval <= fval)) ? 0. : fabs (vval - fval),
00471
00472 ratio = (CoinMax (1., fabs (vval)) /
00473 CoinMax (1., fabs (fval)));
00474
00475
00476
00477 double deldenom = delta/denom;
00478 maxViol = (maxViol > deldenom ? maxViol : deldenom);
00479
00480 if ((delta > 0.) &&
00481 (((ratio > 2.) ||
00482 (ratio < .5)) ||
00483 ((delta /= denom) > CoinMin (COUENNE_EPS, feas_tolerance_)))) {
00484
00485 Jnlst () -> Printf (Ipopt::J_MOREVECTOR, J_PROBLEM,
00486 "checkAux(): auxiliary %d violates tolerance %g by %g (deldenom: %g ratio %g)\n",
00487 i, feas_tolerance_, delta, deldenom, ratio);
00488
00489 isFeas = false;
00490
00491 #ifdef FM_TRACE_NLP
00492 printf("CouenneProblem::checkAux(): auxiliary %d violates tolerance %g by %g (deldenom: %g ratio %g COUENNE_EPS: %g)\n",
00493 i, feas_tolerance_, delta, deldenom, ratio, COUENNE_EPS);
00494 #endif
00495
00496 if(stopAtFirstViol) {
00497 break;
00498 }
00499 }
00500 }
00501 return isFeas;
00502 }
00503
00504
00505
00506 bool CouenneProblem::checkCons(const CouNumber *sol,
00507 const bool stopAtFirstViol,
00508 const double precision, double &maxViol) const {
00509
00510 bool isFeas = true;
00511 for (int i=0; i<nCons(); i++) {
00512
00513 CouenneConstraint *c = Con(i);
00514
00515 CouNumber
00516 body = (*(c -> Body ())) (),
00517 lhs = (*(c -> Lb ())) (),
00518 rhs = (*(c -> Ub ())) ();
00519
00520 double denomUb = 1 + CoinMax (fabs (body), fabs (rhs));
00521 double denomLb = 1 + CoinMax (fabs (body), fabs (lhs));
00522 double violUb = 0, violRelUb = 0, violAbsUb = 0;
00523 if(rhs < COUENNE_INFINITY) {
00524 violAbsUb = body - rhs;
00525 violRelUb = violAbsUb / denomUb;
00526 violUb = violAbsUb - precision * denomUb;
00527
00528 #ifdef FM_USE_ABS_VIOL_CONS
00529 maxViol = (maxViol > violAbsUb ? maxViol : violAbsUb);
00530 #else
00531 maxViol = (maxViol > violRelUb ? maxViol : violRelUb);
00532 #endif
00533
00534 #ifdef FM_TRACE_NLP
00535 printf("violAbsUb: %12.10f violRelUb: %12.10f violUb: %12.10f maxViol: %12.10f\n",
00536 violAbsUb, violRelUb, violUb, maxViol);
00537 #endif
00538 }
00539
00540 double violLb = 0, violRelLb = 0, violAbsLb = 0;
00541 if(lhs > -COUENNE_INFINITY) {
00542 violAbsLb = - body + lhs;
00543 violRelLb = violAbsLb / denomLb;
00544 violLb = violAbsLb - precision * denomLb;
00545
00546 #ifdef FM_USE_ABS_VIOL_CONS
00547 maxViol = (maxViol > violAbsLb ? maxViol : violAbsLb);
00548 #else
00549 maxViol = (maxViol > violRelLb ? maxViol : violRelLb);
00550 #endif
00551
00552 #ifdef FM_TRACE_NLP
00553 printf("violAbsLb: %12.10f violRelLb: %12.10f violLb: %12.10f maxViol: %12.10f\n",
00554 violAbsLb, violRelLb, violLb, maxViol);
00555 #endif
00556 }
00557
00558 #ifdef FM_USE_ABS_VIOL_CONS
00559 if((violAbsUb > precision) || (violAbsLb > precision)) {
00560 if (Jnlst()->ProduceOutput(Ipopt::J_MOREVECTOR, J_PROBLEM)) {
00561
00562 printf ("CouenneProblem::checkCons(): constraint %d violated (lhs=%+e body=%+e rhs=%+e, absolute violation: %g)\n",
00563 i, lhs, body, rhs, CoinMax(violAbsUb, violAbsLb));
00564
00565 c -> print ();
00566 }
00567
00568
00569 #ifdef FM_TRACE_NLP
00570 printf ("CouenneProblem::checkCons(): constraint %d violated (lhs=%+e body=%+e rhs=%+e, absolute violation: %g)\n",
00571 i, lhs, body, rhs, CoinMax (violAbsUb, violAbsLb));
00572 #endif
00573
00574 isFeas = false;
00575 if(stopAtFirstViol) {
00576 break;
00577 }
00578 }
00579 #else
00580 if((violUb > 0) || (violLb > 0)) {
00581 if (Jnlst()->ProduceOutput(Ipopt::J_MOREVECTOR, J_PROBLEM)) {
00582
00583 printf ("CouenneProblem::checkCons(): constraint %d violated (lhs=%+e body=%+e rhs=%+e, relative violation: %g)\n",
00584 i, lhs, body, rhs, CoinMax(violRelUb, violRelLb));
00585
00586 c -> print ();
00587 }
00588
00589
00590 #ifdef FM_TRACE_NLP
00591 printf ("CouenneProblem::checkCons(): constraint %d violated (lhs=%+e body=%+e rhs=%+e, relative violation: %g)\n",
00592 i, lhs, body, rhs, CoinMax (violRelUb, violRelLb));
00593 #endif
00594 isFeas = false;
00595 if(stopAtFirstViol) {
00596 break;
00597 }
00598 }
00599 #endif
00600 }
00601 return(isFeas);
00602 }
00603
00604
00605 bool CouenneProblem::checkNLP2(const double *solution,
00606 const double obj, const bool careAboutObj,
00607 const bool stopAtFirstViol,
00608 const bool checkAll,
00609 const double precision) const {
00610
00611 if(careAboutObj) {
00612 if(stopAtFirstViol) {
00613 printf("CouenneProblem::checkNLP2(): ### ERROR: careAboutObj: true and stopAtFirstViol: true are incompatible\n");
00614 exit(1);
00615 }
00616 }
00617
00618 const std::vector<int> listInt = getRecordBestSol()->getListInt();
00619 bool isFeas = false;
00620 double maxViolCouSol = 0;
00621 double maxViolRecSol = 0;
00622
00623 #ifdef FM_TRACE_NLP
00624 const bool *initIsInt = getRecordBestSol()->getInitIsInt();
00625 printf("Integrality:\n");
00626 for (register int i=0; i<nVars(); i++) {
00627
00628 if (variables_ [i] -> Multiplicity () <= 0)
00629 continue;
00630
00631 if(initIsInt[i]) {
00632 printf(" %d", i);
00633 }
00634 }
00635 printf("\n");
00636
00637 printf("VAR:\n");
00638 for (register int i=0; i<nVars(); i++) {
00639
00640 if (variables_ [i] -> Multiplicity () <= 0)
00641 continue;
00642 exprVar *v = variables_ [i];
00643 if( (v -> Type () == VAR)) {
00644 printf(" %d", i);
00645 }
00646 }
00647 printf("\n");
00648
00649 printf("AUX:\n");
00650 for (register int i=0; i<nVars(); i++) {
00651
00652 if (variables_ [i] -> Multiplicity () <= 0)
00653 continue;
00654 exprVar *v = variables_ [i];
00655 if( (v -> Type () == AUX)) {
00656 printf(" %d", i);
00657 }
00658 }
00659 printf("\n");
00660
00661 printf("mult 0:\n");
00662 for (register int i=0; i<nVars(); i++) {
00663
00664 if (variables_ [i] -> Multiplicity () <= 0) {
00665 printf(" %d", i);
00666 }
00667 }
00668 printf("\n");
00669 #endif
00670
00671 if ((Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_PROBLEM))) {
00672
00673 printf ("checking solution:\n");
00674
00675 for (int i=0; i<nOrigVars_ - ndefined_; i++)
00676 printf ("%.12e ", solution [i]);
00677 printf ("\n");
00678 }
00679
00680 #ifdef FM_TRACE_NLP
00681 printf("CouenneProblem::checkNLP2(): Start checking computed_solution\n");
00682 #endif
00683
00684 int from = 0;
00685 bool isFeasRec = checkInt(solution, from, nOrigVars_ - ndefined_, listInt,
00686 false, stopAtFirstViol,
00687 precision, maxViolRecSol);
00688 bool isFeasCou = isFeasRec;
00689 maxViolCouSol = maxViolRecSol;
00690
00691 if(stopAtFirstViol && !isFeasRec) {
00692
00693 #ifdef FM_TRACE_NLP
00694 printf("CouenneProblem::checkNLP2(): modified_solution is infeasible (some orig vars not integer feasible; violation: %12.10g)\n", maxViolRecSol);
00695 #endif
00696 }
00697
00698 #ifdef CHECK
00699 if(getRecordBestSol()->getCardInitDom() != nVars()) {
00700 printf("CouenneProblem::checkNLP2(): ### ERROR: cardInitDom: %d nVars: %d\n", (getRecordBestSol()->getCardInitDom(), nVars());
00701 exit(1);
00702 }
00703 if(getInitDomLb() == NULL) {
00704 printf("CouenneProblem::checkNLP2(): ### WARNING: initDomLb == NULL\n");
00705 }
00706 if(getInitDomUb() == NULL) {
00707 printf("CouenneProblem::checkNLP2(): ### WARNING: initDomUb == NULL\n");
00708 }
00709 #endif
00710
00711
00712
00713 domain_.push(nVars(), domain_.x(), getRecordBestSol()->getInitDomLb(),
00714 getRecordBestSol()->getInitDomUb(), false);
00715
00716 CouNumber *couRecSol = new CouNumber[nVars()];
00717 CoinCopyN (solution, nOrigVars_ - ndefined_, couRecSol);
00718 getAuxs(couRecSol);
00719
00720
00721
00722 domain_.push(nVars(), couRecSol, getRecordBestSol()->getInitDomLb(),
00723 getRecordBestSol()->getInitDomUb(), false);
00724
00725 if (
00726 #ifdef FM_TRACE_NLP
00727 (1) ||
00728 #endif
00729
00730 (Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_PROBLEM))) {
00731 printf ("checkNLP2(): recomputed_solution: %d vars -------------------\n", domain_.current () -> Dimension ());
00732
00733 double maxDelta = 0;
00734 for (int i=0; i<domain_.current () -> Dimension (); i++) {
00735 printf ("%4d %.12g %.12g [%.12g %.12g]\n",
00736 i, solution[i], domain_.x (i), domain_.lb (i), domain_.ub (i));
00737 maxDelta = (maxDelta > fabs(solution[i] - domain_.x(i)) ?
00738 maxDelta : fabs(solution[i] - domain_.x(i)));
00739 }
00740 printf("maxDelta: %.12g\n", maxDelta);
00741 }
00742
00743 if(checkAll) {
00744 if(!stopAtFirstViol || isFeasRec) {
00745 bool isFeasInt = checkInt(couRecSol, nOrigVars_ - ndefined_, nVars(), listInt,
00746 false, stopAtFirstViol,
00747 precision, maxViolRecSol);
00748 if(!isFeasInt) {
00749
00750 #ifdef FM_TRACE_NLP
00751 printf("CouenneProblem::checkNLP2(): recomputed_solution is infeasible (some aux vars not integer feasible; violation: %12.10g)\n", maxViolRecSol);
00752 #endif
00753
00754 isFeasRec = false;
00755 }
00756 }
00757 }
00758
00759 double objRecSol = checkObj(couRecSol, precision);
00760 double objCouSol = 0;
00761
00762 if(checkAll) {
00763 if(!stopAtFirstViol || isFeasRec) {
00764 bool isFeasBnd = checkBounds(couRecSol, stopAtFirstViol,
00765 precision, maxViolRecSol);
00766 if(!isFeasBnd) {
00767
00768 #ifdef FM_TRACE_NLP
00769 printf("CouenneProblem::checkNLP2(): recomputed_solution is infeasible (violated bounds; violation: %12.10g)\n", maxViolRecSol);
00770 #endif
00771
00772 isFeasRec = false;
00773 }
00774 }
00775 }
00776
00777 if(checkAll) {
00778 if(!stopAtFirstViol || isFeasRec) {
00779 bool isFeasAux = checkAux(couRecSol, stopAtFirstViol,
00780 precision, maxViolRecSol);
00781
00782 if(!isFeasAux) {
00783
00784 #ifdef FM_TRACE_NLP
00785 printf("CouenneProblem::checkNLP2(): recomputed_solution is infeasible (violated Aux; violation: %12.10g)\n", maxViolRecSol);
00786 #endif
00787
00788 isFeasRec = false;
00789 }
00790 }
00791 }
00792
00793 if(!stopAtFirstViol || isFeasRec) {
00794 bool isFeasCons = checkCons(couRecSol, stopAtFirstViol,
00795 precision, maxViolRecSol);
00796 if(!isFeasCons) {
00797
00798 #ifdef FM_TRACE_NLP
00799 printf("CouenneProblem::checkNLP2(): recomputed_solution is infeasible (violated constraint; violation: %12.10g)\n", maxViolRecSol);
00800 #endif
00801
00802 isFeasRec = false;
00803 }
00804 }
00805
00806 #ifdef FM_TRACE_NLP
00807 printf("CouenneProblem::checkNLP2(): end check recomputed_solution (maxViol: %12.10g)\n", maxViolRecSol);
00808 #endif
00809
00810 double objErrorRecSol = objRecSol - obj;
00811 if(!careAboutObj) {
00812 objErrorRecSol = 0;
00813 }
00814
00815 CouNumber *couSol = new CouNumber[nVars()];
00816 bool useRecSol = false;
00817 if(isFeasRec && (objErrorRecSol < precision)) {
00818 useRecSol = true;
00819 isFeas = true;
00820 }
00821 else {
00822
00823 if(checkAll) {
00824
00825
00826 #ifdef FM_TRACE_NLP
00827 printf("CouenneProblem::checkNLP2(): Start checking solution (maxViol: %g)\n",
00828 maxViolCouSol);
00829 #endif
00830
00831 CoinCopyN(solution, nVars(), couSol);
00832 restoreUnusedOriginals(couSol);
00833 domain_.push(nVars(), couSol, getRecordBestSol()->getInitDomLb(),
00834 getRecordBestSol()->getInitDomUb(), false);
00835
00836 if (
00837 #ifdef FM_TRACE_NLP
00838 (1) ||
00839 #endif
00840
00841 (Jnlst () -> ProduceOutput (Ipopt::J_ALL, J_PROBLEM))) {
00842 printf ("checkNLP2(): solution: %d vars -------------------\n", domain_.current () -> Dimension ());
00843
00844 double maxDelta = 0;
00845 for (int i=0; i<domain_.current()->Dimension(); i++) {
00846 printf ("%4d %.12g %.12g [%.12g %.12g]\n",
00847 i, solution[i], domain_.x(i), domain_.lb(i), domain_.ub(i));
00848 maxDelta = (maxDelta > fabs(solution[i] - domain_.x(i)) ?
00849 maxDelta : fabs(solution[i] - domain_.x(i)));
00850 }
00851 printf("maxDelta: %.12g\n", maxDelta);
00852 }
00853
00854 if(!stopAtFirstViol || isFeasCou) {
00855 bool isFeasInt = checkInt(couSol, nOrigVars_ - ndefined_, nVars(), listInt,
00856 false, stopAtFirstViol,
00857 precision, maxViolCouSol);
00858 if(!isFeasInt) {
00859
00860 #ifdef FM_TRACE_NLP
00861 printf("CouenneProblem::checkNLP2(): solution is infeasible (some aux vars not integer feasible; violation: %12.10g)\n", maxViolCouSol);
00862 #endif
00863
00864 isFeasCou = false;
00865 }
00866 }
00867
00868 objCouSol = checkObj(couSol, precision);
00869
00870 if(!stopAtFirstViol || isFeasCou) {
00871 bool isFeasCouBnd = checkBounds(couSol, stopAtFirstViol,
00872 precision, maxViolCouSol);
00873 if(!isFeasCouBnd) {
00874
00875 #ifdef FM_TRACE_NLP
00876 printf("CouenneProblem::checkNLP2(): solution is infeasible (some bounds are violated; violation: %12.10g)\n", maxViolCouSol);
00877 #endif
00878
00879 isFeasCou = false;
00880 }
00881 }
00882
00883 if(!stopAtFirstViol || isFeasCou) {
00884 bool isFeasCouAux = checkAux(couSol, stopAtFirstViol,
00885 precision, maxViolCouSol);
00886 if(!isFeasCouAux) {
00887
00888 #ifdef FM_TRACE_NLP
00889 printf("CouenneProblem::checkNLP2(): solution is infeasible (violated Aux; violation: %12.10g)\n", maxViolCouSol);
00890 #endif
00891
00892 isFeasCou = false;
00893 }
00894 }
00895
00896 if(!stopAtFirstViol || isFeasCou) {
00897 bool isFeasCouCons = checkCons(couSol, stopAtFirstViol,
00898 precision, maxViolCouSol);
00899 if(!isFeasCouCons) {
00900
00901 #ifdef FM_TRACE_NLP
00902 printf("CouenneProblem::checkNLP2(): solution is infeasible (violated constraint; violation: %12.10g)\n", maxViolCouSol);
00903 #endif
00904
00905 isFeasCou = false;
00906 }
00907 }
00908
00909 #ifdef FM_TRACE_NLP
00910 printf("CouenneProblem::checkNLP2(): end check solution (maxViol: %12.10g)\n", maxViolCouSol);
00911 #endif
00912
00913 double objErrorCouSol = objCouSol - obj;
00914 if(!careAboutObj) {
00915 objErrorCouSol = 0;
00916 }
00917 double delObj = objErrorCouSol - objErrorRecSol;
00918 double delViol = maxViolCouSol - maxViolRecSol;
00919
00920 if(isFeasRec) {
00921 if(isFeasCou) {
00922
00923 if(delObj > 0) {
00924 useRecSol = true;
00925 }
00926 else {
00927 useRecSol = false;
00928 }
00929 isFeas = true;
00930 }
00931 else {
00932 useRecSol = true;
00933 isFeas = true;
00934 }
00935 }
00936 else {
00937 if(isFeasCou) {
00938 useRecSol = false;
00939 isFeas = true;
00940 }
00941 else {
00942 isFeas = false;
00943 if(careAboutObj) {
00944 if(fabs(delViol) < 10 * precision) {
00945 useRecSol = (delObj > 0 ? false : true);
00946 }
00947 else {
00948 if(fabs(delObj) < 10 * precision) {
00949 useRecSol = (delViol > 0 ? false : true);
00950 }
00951 else {
00952 double ratObj = fabs(delObj)/(1+fabs(obj));
00953 if(ratObj < fabs(delViol)) {
00954 useRecSol = (delViol > 0 ? false : true);
00955 }
00956 else {
00957 useRecSol = (delObj > 0 ? false : true);
00958 }
00959 }
00960 }
00961 }
00962 else {
00963 if(delViol < 0) {
00964 useRecSol = false;
00965 }
00966 else {
00967 useRecSol = true;
00968 }
00969 }
00970 useRecSol = true;
00971 }
00972 }
00973 domain_.pop ();
00974 }
00975 }
00976
00977 double maxViol = 0;
00978
00979 if(!stopAtFirstViol || isFeas) {
00980 if(useRecSol) {
00981 recBSol->setModSol(couRecSol, nVars(), objRecSol, maxViolRecSol);
00982 maxViol = maxViolRecSol;
00983
00984 #ifdef FM_TRACE_NLP
00985 printf("CouenneProblem::checkNLP2(): select recomputed_solution (maxViol: %12.10g)\n", maxViol);
00986 #endif
00987
00988 }
00989 else {
00990 recBSol->setModSol(couSol, nVars(), objCouSol, maxViolCouSol);
00991 maxViol = maxViolCouSol;
00992
00993 #ifdef FM_TRACE_NLP
00994 printf("CouenneProblem::checkNLP2(): select solution (maxViol: %12.10g)\n", maxViol);
00995 #endif
00996
00997 }
00998 }
00999 delete[] couSol;
01000 delete[] couRecSol;
01001 domain_.pop();
01002 domain_.pop ();
01003
01004 #ifdef FM_TRACE_NLP
01005 if(isFeas) {
01006 printf ("checkNLP2(): RETURN: selected solution is feasible (maxViol: %g)\n", maxViol);
01007 }
01008 else {
01009 printf ("checkNLP2(): RETURN: modified_solution and solution are infeasible\n");
01010 if(!stopAtFirstViol) {
01011 printf("(maxViol: %g)\n", maxViol);
01012 }
01013 else {
01014 printf("\n");
01015 }
01016 }
01017 #endif
01018
01019 return isFeas;
01020 }