00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CoinHelperFunctions.hpp"
00012
00013 #include "OsiRowCut.hpp"
00014
00015 #include "CouenneSolverInterface.hpp"
00016 #include "CouenneProblem.hpp"
00017 #include "CouenneObject.hpp"
00018 #include "CouenneComplBranchingObject.hpp"
00019
00020
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 expression *var,
00034 expression *var2,
00035 int way,
00036 CouNumber brpoint,
00037 bool doFBBT, bool doConvCuts):
00038
00039 CouenneBranchingObject (solver, originalObject, jnlst, var, way, brpoint, doFBBT, doConvCuts),
00040 variable2_ (var2) {
00041
00042 jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING,
00043 "Complem. Branch: x%-3d = 0 or x%-3d = 0\n",
00044 way ? variable_ -> Index () : variable2_ -> Index ());
00045 }
00046
00047
00055 double CouenneComplBranchingObject::branch (OsiSolverInterface * solver) {
00056
00057
00058
00059
00060 int
00061 way = (!branchIndex_) ? firstBranch_ : !firstBranch_,
00062 index = way ? variable2_ -> Index () : variable_ -> Index ();
00063
00064 jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING, "Branching: x%-3d = 0\n",
00065
00066 way ? variable2_ -> Index () : variable_ -> Index ());
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00081
00082 solver -> setColLower (index, 0.);
00083 solver -> setColUpper (index, 0.);
00084
00086
00087 CouenneSolverInterface *couenneSolver = dynamic_cast <CouenneSolverInterface *> (solver);
00088 CouenneProblem *p = couenneSolver -> CutGen () -> Problem ();
00089
00090 int
00091 nvars = p -> nVars (),
00092 objind = p -> Obj (0) -> Body () -> Index ();
00093
00094 p -> domain () -> push (nvars,
00095 solver -> getColSolution (),
00096 solver -> getColLower (),
00097 solver -> getColUpper ());
00098
00099
00100 CouNumber estimate = 0.;
00101
00102 t_chg_bounds *chg_bds = new t_chg_bounds [nvars];
00103
00104 chg_bds [index].setUpper (t_chg_bounds::CHANGED);
00105 chg_bds [index].setLower (t_chg_bounds::CHANGED);
00106
00107 bool infeasible = false;
00108
00109 if ( doFBBT_ &&
00110 p -> doFBBT ()) {
00111
00112 p -> installCutOff ();
00113
00114 if (!p -> btCore (chg_bds))
00115 infeasible = true;
00116 else {
00117
00118 const double
00119 *lb = solver -> getColLower (),
00120 *ub = solver -> getColUpper ();
00121
00122
00123 estimate = CoinMax (0., p -> Lb (objind) - lb [objind]);
00124
00125
00126
00127
00128 for (int i=0; i<nvars; i++) {
00129 if (p -> Lb (i) > lb [i]) solver -> setColLower (i, p -> Lb (i));
00130 if (p -> Ub (i) < ub [i]) solver -> setColUpper (i, p -> Ub (i));
00131 }
00132 }
00133 }
00134
00135 if (!infeasible && doConvCuts_ && simulate_) {
00136
00137
00138 int nchanged, *changed = NULL;
00139 OsiCuts cs;
00140
00141
00142 sparse2dense (nvars, chg_bds, changed, nchanged);
00143 couenneSolver -> CutGen () -> genRowCuts (*solver, cs, nchanged, changed, chg_bds);
00144 free (changed);
00145
00146 solver -> applyCuts (cs);
00147 }
00148
00149 delete [] chg_bds;
00150
00151 p -> domain () -> pop ();
00152
00153
00154 branchIndex_++;
00155
00156 return (infeasible ? COIN_DBL_MAX : estimate);
00157 }