00001
00002
00003
00004
00005
00006
00007
00008
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
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
00061
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
00069 way ? variable2_ -> Index () : variable_ -> Index ());
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00084
00085 int
00086 ind0 = variable_ -> Index (),
00087 ind1 = variable2_ -> Index ();
00088
00089 if (!sign_) {
00090 solver -> setColLower (index, 0.);
00091 solver -> setColUpper (index, 0.);
00092 } else {
00093
00094 if (sign_ < 0)
00095 if (!way) {
00096 solver -> setColUpper (ind0, 0.);
00097 solver -> setColLower (ind1, 0.);
00098 } else {
00099 solver -> setColLower (ind0, 0.);
00100 solver -> setColUpper (ind1, 0.);
00101 }
00102 else
00103 if (!way) {
00104 solver -> setColLower (ind0, 0.);
00105 solver -> setColLower (ind1, 0.);
00106 } else {
00107 solver -> setColUpper (ind0, 0.);
00108 solver -> setColUpper (ind1, 0.);
00109 }
00110 }
00111
00113
00114
00115
00116
00117 int
00118 nvars = problem_ -> nVars (),
00119 objind = problem_ -> Obj (0) -> Body () -> Index ();
00120
00121
00122 CouNumber estimate = 0.;
00123
00124 bool infeasible = false;
00125
00126
00127
00128 if ((doFBBT_ && problem_ -> doFBBT ()) ||
00129 (doConvCuts_ && simulate_ && cutGen_)) {
00130
00131 problem_ -> domain () -> push (nvars,
00132 solver -> getColSolution (),
00133 solver -> getColLower (),
00134 solver -> getColUpper ());
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_ &&
00150 problem_ -> doFBBT ()) {
00151
00152 problem_ -> installCutOff ();
00153
00154 if (!problem_ -> btCore (chg_bds))
00155 infeasible = true;
00156 else {
00157
00158 const double
00159 *lb = solver -> getColLower (),
00160 *ub = solver -> getColUpper ();
00161
00162
00163 estimate = CoinMax (0., problem_ -> Lb (objind) - lb [objind]);
00164
00165
00166
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
00177
00178 int nchanged, *changed = NULL;
00179 OsiCuts cs;
00180
00181
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
00195 branchIndex_++;
00196
00197 return (infeasible ? COIN_DBL_MAX : estimate);
00198 }