/home/coin/SVN-release/OS-2.4.0/Couenne/src/branch/infeasibilityVT.cpp

Go to the documentation of this file.
00001 /* $Id: infeasibilityVT.cpp 694 2011-06-18 20:13:17Z stefan $
00002  *
00003  * Name:    infeasibilityVT.cpp
00004  * Authors: Pietro Belotti, Carnegie Mellon University
00005  * Purpose: Compute violation transfer of a variable. See Tawarmalani
00006  *          and Sahinidis' book or article on MathProg 2002
00007  *
00008  * (C) Carnegie-Mellon University, 2008-09.
00009  * This file is licensed under the Eclipse Public License (EPL)
00010  */
00011 
00012 #include "CoinHelperFunctions.hpp"
00013 #include "CouenneProblem.hpp"
00014 #include "CouenneProblemElem.hpp"
00015 #include "CouenneVTObject.hpp"
00016 
00017 using namespace Ipopt;
00018 using namespace Couenne;
00019 
00022 double CouenneVTObject::infeasibility (const OsiBranchingInformation *info, int &way) const {
00023 
00024   int indexVar = reference_ -> Index ();
00025   assert (indexVar >= 0);
00026 
00027   CouNumber tol = CoinMin (COUENNE_EPS, feas_tolerance_);
00028 
00029   // feasible variable
00030   if (info -> upper_ [indexVar] - 
00031       info -> lower_ [indexVar] <= tol) {
00032     if (reference_ -> isInteger ()) {
00033       double point = info -> solution_ [reference_ -> Index ()];
00034       if (downEstimate_ <       point  - floor (point)) downEstimate_ =       point  - floor (point);
00035       if (upEstimate_   < ceil (point) -        point)  upEstimate_   = ceil (point) -        point;
00036       return intInfeasibility (point,
00037                                info -> lower_ [indexVar],
00038                                info -> upper_ [indexVar]);
00039     } else return (upEstimate_ = downEstimate_ = 0.);
00040   }
00041 
00042   // let Couenne know of current status (variables, bounds)
00043   problem_ -> domain () -> push 
00044     (problem_ -> nVars (),
00045      info -> solution_, 
00046      info -> lower_, 
00047      info -> upper_,
00048      false);
00049 
00050   // debug output ////////////////////////////////////////////////////////////////
00051 
00052   if (jnlst_ -> ProduceOutput (J_DETAILED, J_BRANCHING)) {
00053     printf ("VT infeas on ");
00054     reference_ -> print ();
00055     if (reference_ -> Image ()) { // if no list, print image
00056       printf (" := ");
00057       reference_ -> Image () -> print ();
00058     }
00059     const std::set <int> &dependence = problem_ -> Dependence () [indexVar];
00060     if (dependence.size () > 0) {
00061       printf (" -- ");
00062       for (std::set <int>::const_iterator i = dependence.begin (); 
00063            i != dependence.end (); ++i) {
00064         problem_ -> Var (*i) -> print ();
00065         printf (" ");
00066       }
00067     }
00068     printf ("\n");
00069   }
00070 
00071   // get set of variable indices that depend on reference_
00072   const std::set <int> &dependence = problem_ -> Dependence () [indexVar];
00073 
00074   CouNumber
00075     xcurr    = info -> solution_ [indexVar], // current value of variable
00076     retval   = 0.,                           // will be returned
00077     lFeas    = xcurr,                        // left-most feasible point with all but x_i constant
00078     rFeas    = xcurr,                        // right-most ...
00079     leanLeft = 0.,                           // [0,1],  
00080     fx       = xcurr,                        // value of expression associated with variable (if aux)
00081     maxInf   = 0.;                           // max infeasibility over expressions depending on this
00082 
00083   if (reference_ -> Type () == AUX)
00084     fx = (*(reference_ -> Image ())) ();
00085 
00086   if (dependence.size () == 0) { // this is a top level auxiliary,
00087                                  // nowhere an independent
00088 
00089     // that means, for VT, that letting w vary and keeping everything
00090     // else constant we return the difference between current value
00091     // and value of function at this point
00092 
00093     // these variables may also be disabled in BonCouenneSetup.cpp
00094 
00095     retval = (reference_ -> Type () == AUX) ? // if this is an isolated variable
00096       // check if this w=f(x) is used nowhere and is feasible
00097       (upEstimate_ = downEstimate_ = maxInf = checkInfeasibility (info)) :
00098       0.;
00099 
00100     // check if this w=f(x) is used nowhere and is feasible
00101     retval = upEstimate_ = downEstimate_ = maxInf = checkInfeasibility (info);
00102 
00103   } else {
00104 
00105     // this appears as independent in all auxs of the "dependence" list
00106     // check all non-linear objects containing this variable
00107 
00108     for (std::set <int>::const_iterator i = dependence.begin ();
00109          i != dependence.end (); ++i) {
00110 
00111       const CouenneObject *obj = problem_ -> Objects () [*i];
00112       assert (obj -> Reference ());
00113 
00114       CouNumber 
00115         left   = xcurr,
00116         right  = xcurr,
00117         infeas = obj -> checkInfeasibility (info);
00118 
00119       if (infeas > maxInf)
00120         maxInf = infeas;
00121 
00122       // check feasibility of nonlinear object
00123       if (infeas > 0.) {
00124 
00125         // measure how far have to go, left and right, to restore
00126         // feasibility (see page 582, Tawarmalani and Sahinidis,
00127         // MathProg A: 99, pp. 563-591)
00128         //if (obj. Reference () -> Image ()) // not needed! obj only has nonlinear objects
00129         obj -> Reference () -> Image () -> closestFeasible 
00130           (reference_, obj -> Reference (), left, right);
00131 
00132         if (left  < lFeas) lFeas = left;
00133         if (right > rFeas) rFeas = right;
00134       }
00135 
00136       if (jnlst_ -> ProduceOutput (J_MATRIX, J_BRANCHING)) { // debug output
00137         expression *ref = obj -> Reference ();
00138         jnlst_ -> Printf (J_MATRIX, J_BRANCHING, "[%g,%g] --> %g - %g = %g (diff = %g - %g = %g): ", 
00139                           left, right, rFeas, lFeas, rFeas - lFeas,
00140                           (ref -> Image ()) ? 
00141                           (*(ref-> Image ())) () : 0.,  
00142                           (*(ref)) (),
00143                           (ref -> Image ()) ? 
00144                           (*(ref -> Image ())) () - (*(ref)) () : 0.);
00145         ref -> print (); 
00146         if (ref -> Image ()) 
00147           {printf (" := "); ref -> Image() -> print();}
00148         printf ("\n");
00149       }
00150     }
00151 
00152     if (lFeas < info -> lower_ [indexVar]) lFeas = info -> lower_ [indexVar];
00153     if (rFeas > info -> upper_ [indexVar]) rFeas = info -> upper_ [indexVar];
00154 
00155     retval = rFeas - lFeas;
00156 
00157     upEstimate_   = rFeas - xcurr;
00158     downEstimate_ = xcurr - lFeas;
00159 
00160     // need a nonzero value for the estimate. Although maxInf is
00161     // related to the expressions that depend on this variable, it is
00162     // still an estimate of how the point will change
00163     if (upEstimate_   <= tol) upEstimate_   = maxInf;
00164     if (downEstimate_ <= tol) downEstimate_ = maxInf;
00165   }
00166 
00168 
00169   // object is infeasible. 
00170   // check how in the middle of the interval we are
00171 
00172   const CouNumber threshold = .5; // can be in [0,0.5]
00173 
00174   if (retval > COUENNE_EPS) {
00175 
00176     leanLeft  = (xcurr - lFeas) / retval;
00177 
00178     if      (leanLeft <     threshold) way = 0;
00179     else if (leanLeft > 1 - threshold) way = 1;
00180     else way = (CoinDrand48 () < 0.5) ? 0 : 1;
00181   }
00182 
00183   // done computing delta. Now transfer violation on LP relaxation ///////////////
00184 
00185   // coefficient in objective is in {0,1} and there is only one
00186   // variable with coefficient 1
00187   CouNumber vt_delta =
00188     (indexVar == problem_ -> Obj (0) -> Body () -> Index ()) ? 1. : 0.;
00189 
00190   for (int i=0, n_el = info -> columnLength_ [indexVar]; i < n_el; i++) {
00191 
00192     int indRow = info -> columnStart_ [indexVar] + i;
00193 
00194     vt_delta += 
00195       fabs (info -> pi_ [info -> row_ [indRow]] * 
00196             info -> elementByColumn_  [indRow]);
00197 
00198     //     vt_delta += 
00199     //       info -> pi_ [info -> row_ [indRow]] * 
00200     //       fabs (info -> elementByColumn_  [indRow]);
00201 
00202     jnlst_ -> Printf (J_MATRIX, J_BRANCHING, "+ (pi[%d]=%g) * (el[%d]=%g) [=%g] --> vtd = %g\n",
00203                       info -> row_ [indRow],
00204                       info -> pi_ [info -> row_ [indRow]], 
00205                       indRow,
00206                       info -> elementByColumn_  [indRow],
00207                       info -> pi_ [info -> row_ [indRow]] * 
00208                       info -> elementByColumn_  [indRow],
00209                       vt_delta);
00210   }
00211 
00212   // weights for VT itself and width of interval
00213   const CouNumber 
00214     alpha = 1.0,
00215     beta  = 0.0;
00216 
00217   jnlst_ -> Printf (J_MATRIX, J_BRANCHING, "return %g * %g + %g * %g + %g * %g --> ", 
00218                     alpha, fabs (retval * vt_delta), beta, retval,
00219                     1-alpha-beta, leanLeft * (1-leanLeft));
00220 
00221   retval = 
00222     alpha          * fabs (retval*vt_delta) +  // violation transfer itself
00223     beta           * retval +                  // width of feasibility interval
00224     (1-alpha-beta) * leanLeft * (1-leanLeft);  // how in the middle of the interval x is
00225 
00226   if (jnlst_ -> ProduceOutput (J_MATRIX, J_BRANCHING)) {
00227     if (retval > tol) {
00228       printf ("vt-delta is %-10g [", retval); 
00229       reference_ -> print (); 
00230       if (reference_ -> Image ()) { // if no list, print image
00231         printf (" := ");
00232         reference_ -> Image () -> print ();
00233       }
00234       if (dependence.size () > 0) {
00235         printf (" -- ");
00236         for (std::set <int>::const_iterator i = dependence.begin (); 
00237              i != dependence.end (); ++i) {
00238           problem_ -> Var (*i) -> print ();
00239           printf (" ");
00240         }
00241       }
00242       printf ("]\n");
00243     } else printf ("feasible...\n");
00244   }
00245 
00246   problem_ -> domain () -> pop ();
00247 
00248   if ((retval <= tol) &&
00249       (maxInf > tol)) {
00250 
00251     // no improvement with this variable, but need to return nonzero
00252     // if this is an auxiliary whose value is different from relative
00253     // expression
00254     retval = maxInf; 
00255   }
00256 
00257   if (retval <= tol) 
00258     retval = 0.;
00259 
00260 #define ALMOST_ZERO 1e-8
00261 
00262   assert ((retval < ALMOST_ZERO && upEstimate_ < ALMOST_ZERO && downEstimate_ < ALMOST_ZERO) ||
00263           (retval > ALMOST_ZERO && upEstimate_ > ALMOST_ZERO && downEstimate_ > ALMOST_ZERO));
00264 
00265   return (reference_ -> isInteger ()) ? 
00266     CoinMax (retval, intInfeasibility (info -> solution_ [indexVar],
00267                                        info -> lower_    [indexVar],
00268                                        info -> upper_    [indexVar])) :
00269     retval;
00270 }

Generated on Thu Sep 22 03:05:56 2011 by  doxygen 1.4.7