/home/coin/SVN-release/OS-2.0.1/Couenne/src/branch/CouenneVarObject.cpp

Go to the documentation of this file.
00001 /* $Id: CouenneVarObject.cpp 155 2009-06-16 20:19:39Z pbelotti $
00002  *
00003  * Name:    CouenneVarObject.cpp
00004  * Authors: Pietro Belotti, Carnegie Mellon University
00005  * Purpose: Base object for variables (to be used in branching)
00006  *
00007  * (C) Carnegie-Mellon University, 2008.
00008  * This file is licensed under the Common Public License (CPL)
00009  */
00010 
00011 #include "CoinHelperFunctions.hpp"
00012 
00013 #include "CouenneProblem.hpp"
00014 #include "CouenneVarObject.hpp"
00015 #include "CouenneBranchingObject.hpp"
00016 #include "CouenneComplObject.hpp"
00017 
00019 CouenneVarObject::CouenneVarObject (CouenneProblem *p,
00020                                     exprVar *ref, 
00021                                     Bonmin::BabSetupBase *base, 
00022                                     JnlstPtr jnlst):
00023 
00024   // Do not set variable (expression).
00025   // This way, no expression-dependent strategy is chosen
00026   CouenneObject (p, ref, base, jnlst) {
00027 
00028   if (jnlst_ -> ProduceOutput (J_SUMMARY, J_BRANCHING)) {
00029     printf ("created Variable Object: "); 
00030     reference_ -> print (); 
00031     printf (" with %s strategy [clamp=%g, alpha=%g]\n", 
00032             (strategy_ == LP_CLAMPED)   ? "lp-clamped" : 
00033             (strategy_ == LP_CENTRAL)   ? "lp-central" : 
00034             (strategy_ == BALANCED)     ? "balanced"   : 
00035             (strategy_ == MIN_AREA)     ? "min-area"   : 
00036             (strategy_ == MID_INTERVAL) ? "mid-point"  : 
00037             (strategy_ == NO_BRANCH)    ? "no-branching (null infeasibility)" : 
00038                                           "no strategy",
00039             lp_clamp_, alpha_);
00040   }
00041 }
00042 
00043 
00045 OsiBranchingObject *CouenneVarObject::createBranch (OsiSolverInterface *si, 
00046                                                     const OsiBranchingInformation *info, 
00047                                                     int way) const {
00048 
00049   // The infeasibility on an (independent) variable x_i is given by
00050   // something more elaborate than |w-f(x)|, that is, a function of
00051   // all infeasibilities of all expressions which depend on x_i.
00052 
00053   problem_ -> domain () -> push 
00054     (problem_ -> nVars (),
00055      info -> solution_,
00056      info -> lower_,
00057      info -> upper_); // have to alloc+copy
00058 
00059   int bestWay;
00060   const CouenneObject *criticalObject = NULL; // should create the branchingObject
00061 
00062   CouNumber bestPt = computeBranchingPoint (info, bestWay, criticalObject);
00063 
00065 
00066   jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING, ":::: creating branching on x_%d @%g [%g,%g]\n", 
00067           reference_ -> Index (), 
00068           info -> solution_ [reference_ -> Index ()],
00069           info -> lower_    [reference_ -> Index ()],
00070           info -> upper_    [reference_ -> Index ()]);
00071 
00072   OsiBranchingObject *brObj = criticalObject ? 
00073     criticalObject -> createBranch (si, info, way) :
00074     new CouenneBranchingObject (si, this, jnlst_, reference_, way, bestPt, doFBBT_, doConvCuts_);
00075 
00076   problem_ -> domain () -> pop ();
00077 
00078   return brObj;
00079 }
00080 
00081 
00083 CouNumber CouenneVarObject::computeBranchingPoint(const OsiBranchingInformation *info,
00084                                                   int& bestWay,
00085                                                   const CouenneObject *&criticalObject) const {
00086   criticalObject = NULL;
00087 
00088   if (jnlst_ -> ProduceOutput (J_DETAILED, J_BRANCHING)) {
00089     printf ( "---------- computeBRPT for "); 
00090     reference_ -> print (); 
00091     printf (" [%g,%g]\n", 
00092             info -> lower_ [reference_ -> Index ()],
00093             info -> upper_ [reference_ -> Index ()]);
00094   }
00095 
00096   expression *brVar = NULL; // branching variable
00097 
00098   CouNumber
00099     brdistDn = 0.,
00100     brdistUp = 0.,
00101     bestPt   = 0.,
00102    *brPts    = NULL, // branching point(s)
00103    *brDist   = NULL, // distances from LP point to each new convexification
00104     maxdist = - COIN_DBL_MAX;
00105 
00106   bool chosen = false;
00107 
00108   bestWay = TWO_LEFT;
00109   int whichWay = TWO_LEFT,
00110     index = reference_ -> Index ();
00111 
00112   std::set <int> deplist = problem_ -> Dependence () [index];
00113 
00114   for (std::set <int>::iterator i = deplist.begin (); i != deplist.end (); ++i) {
00115 
00116     const CouenneObject &obj = problem_ -> Objects () [*i];
00117 
00118     CouNumber improv = 0.;
00119 
00120     assert (obj. Reference ());
00121 
00122     if (jnlst_ -> ProduceOutput (J_MATRIX, J_BRANCHING)) {
00123       printf ("  ** "); 
00124       obj. Reference () -> print (); 
00125       if (reference_ -> Image ()) {printf (" := "); obj. Reference () -> Image () -> print ();}
00126       printf ("\n");
00127     }
00128 
00129     if (obj. Reference ()) {
00130       if (obj. Reference () -> Image ())
00131         improv = obj. Reference () -> Image ()
00132           -> selectBranch (&obj, info,                      // input parameters
00133                            brVar, brPts, brDist, whichWay); // result: who, where, distances, direction
00134       else {
00135         brVar = obj. Reference ();
00136         brPts  = (double *) realloc (brPts, sizeof (double)); 
00137         brDist = (double *) realloc (brDist, 2 * sizeof (double)); 
00138 
00139         double point = info -> solution_ [obj. Reference () -> Index ()];
00140 
00141         *brPts = point;
00142         improv = 0.;
00143 
00144         if (point > floor (point)) {improv =                  brDist [0] = point - floor (point);}
00145         if (point < ceil  (point)) {improv = CoinMin (improv, brDist [1] = ceil (point) - point);}
00146 
00147         point -= floor (point);
00148         whichWay = (point < 0.45) ? TWO_LEFT : (point > 0.55) ? TWO_RIGHT : TWO_RAND;
00149       }
00150     }
00151 
00152     if (jnlst_ -> ProduceOutput (J_MATRIX, J_BRANCHING)) {
00153       printf ("  --> "); 
00154       if (brVar) {
00155         brVar -> print (); 
00156         if (brPts) 
00157           printf (" at %g, improv %g <%g>, indices = %d,%d\n", 
00158                   *brPts, improv, maxdist, index, brVar -> Index ());
00159       }
00160     }
00161 
00162     if (brVar &&
00163         (brVar -> Index () == index) &&    // it's us!
00164         (fabs (improv) > maxdist) &&       // this branching seems to induce a higher improvement
00165         (fabs (*brPts) < COU_MAX_COEFF)) { // and branching pt is limited
00166 
00167       criticalObject = &(problem_ -> Objects () [*i]); // set this object as the branch creator
00168 
00169       brdistDn = brDist [0];
00170       brdistUp = brDist [1];
00171       chosen = true;
00172       bestPt = *brPts;
00173       maxdist = improv;
00174       bestWay = whichWay;
00175     }
00176   }
00177 
00178   // no hits on this VarObject's variable, that is, this variable was
00179   // never chosen 
00180 
00181   if (!chosen) {
00182 
00183     bestPt = info -> solution_ [index];
00184     brVar  = reference_;
00185 
00186     CouNumber 
00187       l     = info -> lower_ [index], 
00188       u     = info -> upper_ [index],
00189       width = lp_clamp_ * (u-l);
00190 
00191     switch (strategy_) {
00192 
00193     case CouenneObject::LP_CLAMPED:
00194       bestPt = CoinMax (l + width, CoinMin (bestPt, u - width));
00195       break;
00196     case CouenneObject::LP_CENTRAL: 
00197       if ((bestPt < l + width) || (bestPt > u - width))
00198         bestPt = (l+u)/2;
00199       break;
00200     case CouenneObject::MID_INTERVAL: 
00201     default: 
00202       // all other cases (balanced, min-area)
00203       bestPt = midInterval (bestPt, l, u);
00204 
00205       if (jnlst_ -> ProduceOutput (J_MATRIX, J_BRANCHING)) {
00206         if (CoinMin (fabs (bestPt - l), fabs (bestPt - u)) < 1e-3) {
00207           printf ("computed failsafe %g [%g,%g] for ", bestPt, l,u);
00208           reference_ -> print (); printf ("\n");
00209         }
00210       }
00211       break;
00212     }
00213 
00214     brPts  = (double *) realloc (brPts, sizeof (double));
00215     *brPts = bestPt;
00216 
00217       if (jnlst_ -> ProduceOutput (J_MATRIX, J_BRANCHING)) {
00218         printf ("  ::: failsafe:  %g [%g,%g] for ", 
00219                 bestPt, info -> lower_ [index], info -> upper_ [index]); 
00220         reference_ -> print ();
00221         printf ("\n");
00222       }
00223 
00224   } else {
00225 
00226       if (jnlst_ -> ProduceOutput (J_MATRIX, J_BRANCHING)) {
00227         if (CoinMin (fabs (bestPt - info -> lower_ [index]), 
00228                      fabs (bestPt - info -> upper_ [index])) < 1e-3) {
00229           printf ("  computed %g [%g,%g] for ", 
00230                   bestPt, info -> lower_ [index], info -> upper_ [index]); 
00231           reference_ -> print ();
00232           printf ("\n");
00233         }
00234       }
00235   }
00236 
00237   if (pseudoMultType_ == PROJECTDIST) {
00238 
00239     if (chosen) {
00240       downEstimate_ = brdistDn;
00241       upEstimate_   = brdistUp;
00242     } 
00243     else downEstimate_ = upEstimate_ = 1.;
00244   }
00245 
00246   if (brPts)  free (brPts);
00247   if (brDist) free (brDist);
00248 
00249   return bestPt;
00250 }
00251 
00252 
00253 #define TOL 0.
00254 
00256 double CouenneVarObject::feasibleRegion (OsiSolverInterface *solver, 
00257                                          const OsiBranchingInformation *info) const {
00258   int index = reference_ -> Index ();
00259 
00260   assert (index >= 0);
00261 
00262   double val = info -> solution_ [index];
00263 
00264   // fix that variable to its current value
00265   solver -> setColLower (index, val-TOL);
00266   solver -> setColUpper (index, val+TOL);
00267 
00268   return 0.;
00269 }
00270 
00271 
00273 bool CouenneVarObject::isCuttable () const {
00274 
00275   const std::set <int>              &deplist = problem_ -> Dependence () [reference_ -> Index ()];
00276   const std::vector <CouenneObject> &objects = problem_ -> Objects ();
00277 
00278   for (std::set <int>::const_iterator depvar = deplist. begin ();
00279        depvar != deplist. end (); ++depvar)
00280     if (!(objects [*depvar]. isCuttable ()))
00281       return false;
00282 
00283   return (!(reference_ -> isInteger ()));
00284 }
00285 

Generated on Thu Oct 8 03:02:56 2009 by  doxygen 1.4.7