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