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