/home/coin/SVN-release/OS-2.2.0/Couenne/src/branch/CouenneComplBranchingObject.cpp

Go to the documentation of this file.
00001 /* $Id: CouenneComplBranchingObject.cpp 260 2009-10-04 14:22:01Z pbelotti $
00002  *
00003  * Name:    CouenneComplBranchingObject.cpp
00004  * Authors: Pietro Belotti, Carnegie Mellon University
00005  * Purpose: Branching object for auxiliary variables
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 
00013 #include "OsiRowCut.hpp"
00014 
00015 #include "CouenneProblem.hpp"
00016 #include "CouenneObject.hpp"
00017 #include "CouenneComplBranchingObject.hpp"
00018 #include "CouenneCutGenerator.hpp"
00019 
00020 // translate changed bound sparse array into a dense one
00021 void sparse2dense (int ncols, t_chg_bounds *chg_bds, int *&changed, int &nchanged);
00022 
00023 
00030 CouenneComplBranchingObject::CouenneComplBranchingObject (OsiSolverInterface *solver,
00031                                                           const OsiObject * originalObject,
00032                                                           JnlstPtr jnlst, 
00033                                                           CouenneCutGenerator *c,
00034                                                           CouenneProblem *p,
00035                                                           expression *var, 
00036                                                           expression *var2, 
00037                                                           int way, 
00038                                                           CouNumber brpoint, 
00039                                                           bool doFBBT, bool doConvCuts, int sign):
00040 
00041   CouenneBranchingObject (solver, originalObject, jnlst, c, p, var, way, brpoint, doFBBT, doConvCuts),
00042   variable2_    (var2),
00043   sign_         (sign) {
00044 
00045   jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING, 
00046                     "Complem. Branch: x%-3d = 0 or x%-3d = 0\n", 
00047                     way ? variable_ -> Index () : variable2_ -> Index ());
00048 }
00049 
00050 
00058 double CouenneComplBranchingObject::branch (OsiSolverInterface * solver) {
00059 
00060   // way = 0 if "x1=0" node, 
00061   //       1 if "x2=0" node
00062 
00063   int 
00064     way   = (!branchIndex_) ? firstBranch_ : !firstBranch_,
00065     index = way ? variable2_ -> Index () : variable_ -> Index ();
00066 
00067   jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING, "Branching: x%-3d = 0\n", 
00068                     //printf ("complementarity Branching: x%-3d = 0\n", 
00069                     way ? variable2_ -> Index () : variable_ -> Index ());
00070 
00071   /*
00072   double time = CoinCpuTime ();
00073   jnlst_ -> Printf (J_VECTOR, J_BRANCHING,"[vbctool] %02d:%02d:%02d.%02d_I x%d%c=%g_[%g,%g]\n",
00074                     (int) (floor(time) / 3600), 
00075                     (int) (floor(time) / 60) % 60, 
00076                     (int) floor(time) % 60, 
00077                     (int) ((time - floor (time)) * 100),
00078                     index, way ? '>' : '<', integer ? ((way ? ceil (brpt): floor (brpt))) : brpt,
00079                     solver -> getColLower () [index],
00080                     solver -> getColUpper () [index]);
00081   */
00082 
00084 
00085   int 
00086     ind0 = variable_  -> Index (),
00087     ind1 = variable2_ -> Index ();
00088 
00089   if (!sign_) { // constraint x1 x2 = 0
00090     solver -> setColLower (index, 0.);
00091     solver -> setColUpper (index, 0.);
00092   } else {
00093 
00094     if (sign_ < 0) // it is a x1 x2 <= 0
00095       if (!way) {  // branch on second orthant first
00096         solver -> setColUpper (ind0, 0.);
00097         solver -> setColLower (ind1, 0.);
00098       } else {     // branch on fourth orthant first
00099         solver -> setColLower (ind0, 0.);
00100         solver -> setColUpper (ind1, 0.);
00101       }
00102     else           // it is a x1 x2 >= 0
00103       if (!way) {  // branch on first orthant first
00104         solver -> setColLower (ind0, 0.);
00105         solver -> setColLower (ind1, 0.);
00106       } else {     // branch on third orthant first
00107         solver -> setColUpper (ind0, 0.);
00108         solver -> setColUpper (ind1, 0.);
00109       }
00110   }
00111 
00113 
00114   //CouenneSolverInterface *couenneSolver = dynamic_cast <CouenneSolverInterface *> (solver);
00115   //CouenneProblem *p = couenneSolver -> CutGen () -> Problem ();
00116 
00117   int 
00118     nvars  = problem_ -> nVars (),
00119     objind = problem_ -> Obj (0) -> Body () -> Index ();
00120 
00121   //CouNumber &estimate = way ? upEstimate_ : downEstimate_;
00122   CouNumber estimate = 0.;//way ? upEstimate_ : downEstimate_;
00123 
00124   bool infeasible = false;
00125 
00126   // only bother doing all of the below if the allocated and pushed
00127   // stuff will be really used
00128   if ((doFBBT_ && problem_ -> doFBBT ()) ||
00129       (doConvCuts_ && simulate_ && cutGen_)) { 
00130 
00131     problem_ -> domain () -> push (nvars,
00132                                    solver -> getColSolution (), 
00133                                    solver -> getColLower    (), 
00134                                    solver -> getColUpper    ()); // have to alloc+copy
00135 
00136     t_chg_bounds *chg_bds = new t_chg_bounds [nvars];
00137 
00138     if (!sign_) {
00139       chg_bds [index].setLower (t_chg_bounds::CHANGED);
00140       chg_bds [index].setUpper (t_chg_bounds::CHANGED);
00141     } else {
00142       chg_bds [ind0].setLower (t_chg_bounds::CHANGED);
00143       chg_bds [ind0].setUpper (t_chg_bounds::CHANGED);
00144 
00145       chg_bds [ind1].setLower (t_chg_bounds::CHANGED);
00146       chg_bds [ind1].setUpper (t_chg_bounds::CHANGED);
00147     }
00148 
00149     if (            doFBBT_ &&           // this branching object should do FBBT, and
00150         problem_ -> doFBBT ()) {         // problem allowed to do FBBT
00151 
00152       problem_ -> installCutOff ();
00153 
00154       if (!problem_ -> btCore (chg_bds)) // done FBBT and this branch is infeasible
00155         infeasible = true;        // ==> report it
00156       else {
00157 
00158         const double
00159           *lb = solver -> getColLower (),
00160           *ub = solver -> getColUpper ();
00161 
00162         //CouNumber newEst = problem_ -> Lb (objind) - lb [objind];
00163         estimate = CoinMax (0., problem_ -> Lb (objind) - lb [objind]);
00164 
00165         //if (newEst > estimate) 
00166         //estimate = newEst;
00167 
00168         for (int i=0; i<nvars; i++) {
00169           if (problem_ -> Lb (i) > lb [i]) solver -> setColLower (i, problem_ -> Lb (i));
00170           if (problem_ -> Ub (i) < ub [i]) solver -> setColUpper (i, problem_ -> Ub (i));
00171         }
00172       }
00173     }
00174 
00175     if (!infeasible && doConvCuts_ && simulate_ && cutGen_) { 
00176       // generate convexification cuts before solving new node's LP
00177 
00178       int nchanged, *changed = NULL;
00179       OsiCuts cs;
00180 
00181       // sparsify structure with info on changed bounds and get convexification cuts
00182       sparse2dense (nvars, chg_bds, changed, nchanged);
00183       cutGen_ -> genRowCuts (*solver, cs, nchanged, changed, chg_bds);
00184       free (changed);
00185 
00186       solver -> applyCuts (cs);
00187     }
00188 
00189     delete [] chg_bds;
00190 
00191     problem_ -> domain () -> pop ();
00192   }
00193 
00194   // next time do other branching
00195   branchIndex_++;
00196 
00197   return (infeasible ? COIN_DBL_MAX : estimate); // estimated change in objective function
00198 }

Generated on Thu Aug 5 03:02:56 2010 by  doxygen 1.4.7