/home/coin/SVN-release/OS-2.0.0/Couenne/src/problem/checkNLP.cpp

Go to the documentation of this file.
00001 /* $Id: checkNLP.cpp 154 2009-06-16 18:52:53Z pbelotti $ */
00002 /*
00003  * Name:    checkNLP.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: check NLP feasibility of incumbent integer solution
00006  *
00007  * (C) Carnegie-Mellon University, 2006-09.
00008  * This file is licensed under the Common Public License (CPL)
00009  */
00010 
00011 #include "CoinHelperFunctions.hpp"
00012 #include "CouenneProblem.hpp"
00013 
00014 // check if solution is MINLP feasible
00015 bool CouenneProblem::checkNLP (const double *solution, double &obj, bool recompute) const {
00016 
00017   const int infeasible = 1;
00018   const int wrong_obj  = 2;
00019 
00020   /*printf ("checking solution: [%.12e] ", obj);
00021   for (int i=0; i<nOrigVars_; i++)
00022     printf ("%.12e ", solution [i]);
00023     printf ("\n");*/
00024 
00025   // pre-check on original variables
00026   for (int i=0; i < nOrigVars_; i++) {
00027 
00028     CouNumber val = solution [i];
00029 
00030     // check (original and auxiliary) variables' integrality
00031 
00032     if ((variables_ [i] -> isInteger ()) &&
00033         (variables_ [i] -> Type () == VAR) &&
00034         (variables_ [i] -> Multiplicity () > 0) &&
00035         (fabs (val - COUENNE_round (val)) > feas_tolerance_)) {
00036 
00037       Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00038                       "checkNLP: integrality %d violated: %.6f [%g,%g]\n", 
00039                       i, val, domain_.lb (i), domain_.ub (i));
00040 
00041       return false;
00042     }
00043   }
00044 
00045   CouNumber *sol = new CouNumber [nVars ()];
00046 
00047   // copy solution, evaluate the corresponding aux, and then replace
00048   // the original variables again for checking
00049   CoinCopyN (solution, nOrigVars_, sol);
00050   getAuxs (sol);
00051   CoinCopyN (solution, nOrigVars_, sol);
00052 
00053   // install NL solution candidate in evaluation structure
00054   domain_.push (nVars (), sol, domain_.lb (), domain_.ub (), false);
00055 
00056   /*printf ("checknlp: %d vars -------------------\n", domain_.current () -> Dimension ());
00057   for (int i=0; i<domain_.current () -> Dimension (); i++)
00058     printf ("%4d %.12e [%.12e %.12e]\n", 
00059     i, domain_.x (i), domain_.lb (i), domain_.ub (i));*/
00060 
00061   expression *objBody = Obj (0) -> Body ();
00062 
00063   // BUG: if Ipopt solution violates bounds of original variables and
00064   // objective depends on originals, we may have a "computed object"
00065   // out of bounds
00066 
00067   //CouNumber realobj = (*(objBody -> Image () ? objBody -> Image () : objBody)) ();
00068   CouNumber realobj = obj;
00069 
00070   if (objBody) 
00071     realobj = 
00072       (objBody -> Index () >= 0) ?
00073       sol [objBody -> Index ()] : 
00074       (*(objBody -> Image () ? objBody -> Image () : objBody)) ();
00075 
00076   /*printf ("%.12e %.12e %.12e ------------------------------\n", 
00077           realobj, sol [objBody -> Index ()], 
00078           (*(objBody -> Image () ? objBody -> Image () : objBody)) ());*/
00079 
00080   bool retval = true;
00081 
00082   try {
00083 
00084     // check if objective corresponds
00085 
00086     if (fabs (realobj - obj) / (1. + fabs (realobj)) > feas_tolerance_) {
00087 
00088       Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00089                       "checkNLP: false objective. %g != %g (diff. %g)\n", 
00090                       realobj, obj, realobj - obj);
00091 
00092       if (!recompute)
00093         throw wrong_obj;
00094     }
00095 
00096     if (recompute)
00097       obj = realobj;
00098 
00099     //printf ("recomputed: %.12e\n", obj);
00100 
00101     for (int i=0; i < nOrigVars_; i++) {
00102 
00103       if (variables_ [i] -> Multiplicity () <= 0) 
00104         continue;
00105 
00106       CouNumber val = domain_.x (i);
00107 
00108       // check bounds
00109 
00110       if ((val > domain_.ub (i) + feas_tolerance_) ||
00111           (val < domain_.lb (i) - feas_tolerance_)) {
00112 
00113         Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00114                         "checkNLP: variable %d out of bounds: %.6f [%g,%g] (diff %g)\n", 
00115                         i, val, domain_.lb (i), domain_.ub (i),
00116                         CoinMax (fabs (val - domain_.lb (i)), 
00117                                  fabs (val - domain_.ub (i))));
00118         throw infeasible;
00119       }
00120 
00121       // check (original and auxiliary) variables' integrality
00122 
00123       if (variables_ [i] -> isInteger () &&
00124           (fabs (val - COUENNE_round (val)) > feas_tolerance_)) {
00125 
00126         Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00127                         "checkNLP: integrality %d violated: %.6f [%g,%g]\n", 
00128                         i, val, domain_.lb (i), domain_.ub (i));
00129 
00130         throw infeasible;
00131       }
00132 
00133       /*if (variables_ [i] -> Type () == AUX) {
00134         printf ("checking aux ");
00135         variables_ [i] -> print (); printf (" := ");
00136         variables_ [i] -> Image () -> print (); 
00137         printf (" --- %.12e = %.12e [%.12e]; {", 
00138                 (*(variables_ [i])) (), 
00139                 (*(variables_ [i] -> Image ())) (),
00140                 (*(variables_ [i])) () -
00141                 (*(variables_ [i] -> Image ())) ());
00142         for (int j=0; j<nVars (); j++)
00143           printf ("%.12e ", (*(variables_ [j])) ());
00144         printf ("}\n");
00145         }*/
00146 
00147       CouNumber delta;
00148 
00149       // check if auxiliary has zero infeasibility
00150 
00151       if ((variables_ [i] -> Type () == AUX) && 
00152           (fabs (delta = (*(variables_ [i])) () - 
00153                  (*(variables_ [i] -> Image ())) ()) > feas_tolerance_)) {
00154 
00155         Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00156                         "checkNLP: auxiliarized %d violated (%g)\n", i, delta);
00157 
00158         throw infeasible;
00159       }
00160     }
00161 
00162     // check constraints
00163 
00164     for (int i=0; i < nCons (); i++) {
00165 
00166       CouenneConstraint *c = Con (i);
00167 
00168       CouNumber
00169         body = (*(c -> Body ())) (),
00170         lhs  = (*(c -> Lb   ())) (),
00171         rhs  = (*(c -> Ub   ())) ();
00172 
00173       if ((rhs < COUENNE_INFINITY) &&
00174            (body > rhs + feas_tolerance_ * (1 + CoinMax (fabs (body), fabs (rhs)))) || 
00175           (lhs > -COUENNE_INFINITY) &&
00176           (body < lhs - feas_tolerance_ * (1 + CoinMax (fabs (body), fabs (lhs))))) {
00177 
00178         if (Jnlst()->ProduceOutput(Ipopt::J_MOREVECTOR, J_PROBLEM)) {
00179 
00180           Jnlst()->Printf
00181             (Ipopt::J_MOREVECTOR, J_PROBLEM,
00182              "checkNLP: constraint %d violated (lhs=%+e body=%+e rhs=%+e, violation %g): ",
00183              i, lhs, body, rhs, CoinMax (lhs-body, body-rhs));
00184 
00185           c -> print ();
00186         }
00187 
00188         throw infeasible;
00189       }
00190     }
00191   }
00192 
00193   catch (int exception) {
00194 
00195     switch (exception) {
00196 
00197     case wrong_obj:
00198       retval = false;
00199       break;
00200 
00201     case infeasible:
00202     default:
00203       retval = false;
00204       break;
00205     }
00206   }
00207 
00208   delete [] sol;
00209   domain_.pop ();
00210 
00211   return retval;
00212 }

Generated on Mon Aug 3 03:02:21 2009 by  doxygen 1.4.7