00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CoinHelperFunctions.hpp"
00012
00013 #include "OsiRowCut.hpp"
00014
00015 #include "CouenneCutGenerator.hpp"
00016 #include "CouenneProblem.hpp"
00017 #include "CouenneProblemElem.hpp"
00018 #include "CouenneObject.hpp"
00019 #include "CouenneComplBranchingObject.hpp"
00020
00021 using namespace Ipopt;
00022 using namespace Couenne;
00023
00024
00025 void sparse2dense (int ncols, t_chg_bounds *chg_bds, int *&changed, int &nchanged);
00026
00027
00034 CouenneComplBranchingObject::CouenneComplBranchingObject (OsiSolverInterface *solver,
00035 const OsiObject * originalObject,
00036 JnlstPtr jnlst,
00037 CouenneCutGenerator *c,
00038 CouenneProblem *p,
00039 expression *var,
00040 expression *var2,
00041 int way,
00042 CouNumber brpoint,
00043 bool doFBBT, bool doConvCuts, int sign):
00044
00045 CouenneBranchingObject (solver, originalObject, jnlst, c, p, var, way, brpoint, doFBBT, doConvCuts),
00046 variable2_ (var2),
00047 sign_ (sign) {
00048
00049 jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING,
00050 "Complem. Branch: x%-3d = 0 or x%-3d = 0\n",
00051 way ? variable_ -> Index () : variable2_ -> Index ());
00052 }
00053
00054
00062 double CouenneComplBranchingObject::branch (OsiSolverInterface * solver) {
00063
00064
00065
00066
00067 int
00068 way = (!branchIndex_) ? firstBranch_ : !firstBranch_,
00069 index = way ? variable2_ -> Index () : variable_ -> Index ();
00070
00071 jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING, "Branching: x%-3d = 0\n",
00072
00073 way ? variable2_ -> Index () : variable_ -> Index ());
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00088
00089 int
00090 ind0 = variable_ -> Index (),
00091 ind1 = variable2_ -> Index ();
00092
00093 if (!sign_) {
00094 solver -> setColLower (index, 0.);
00095 solver -> setColUpper (index, 0.);
00096 } else {
00097
00098 if (sign_ < 0)
00099 if (!way) {
00100 solver -> setColUpper (ind0, 0.);
00101 solver -> setColLower (ind1, 0.);
00102 } else {
00103 solver -> setColLower (ind0, 0.);
00104 solver -> setColUpper (ind1, 0.);
00105 }
00106 else
00107 if (!way) {
00108 solver -> setColLower (ind0, 0.);
00109 solver -> setColLower (ind1, 0.);
00110 } else {
00111 solver -> setColUpper (ind0, 0.);
00112 solver -> setColUpper (ind1, 0.);
00113 }
00114 }
00115
00117
00118
00119
00120
00121 int
00122 nvars = problem_ -> nVars (),
00123 objind = problem_ -> Obj (0) -> Body () -> Index ();
00124
00125
00126 CouNumber estimate = 0.;
00127
00128 bool infeasible = false;
00129
00130
00131
00132 if ((doFBBT_ && problem_ -> doFBBT ()) ||
00133 (doConvCuts_ && simulate_ && cutGen_)) {
00134
00135 problem_ -> domain () -> push (nvars,
00136 solver -> getColSolution (),
00137 solver -> getColLower (),
00138 solver -> getColUpper ());
00139
00140 t_chg_bounds *chg_bds = new t_chg_bounds [nvars];
00141
00142 if (!sign_) {
00143 chg_bds [index].setLower (t_chg_bounds::CHANGED);
00144 chg_bds [index].setUpper (t_chg_bounds::CHANGED);
00145 } else {
00146 chg_bds [ind0].setLower (t_chg_bounds::CHANGED);
00147 chg_bds [ind0].setUpper (t_chg_bounds::CHANGED);
00148
00149 chg_bds [ind1].setLower (t_chg_bounds::CHANGED);
00150 chg_bds [ind1].setUpper (t_chg_bounds::CHANGED);
00151 }
00152
00153 if ( doFBBT_ &&
00154 problem_ -> doFBBT ()) {
00155
00156 problem_ -> installCutOff ();
00157
00158 if (!problem_ -> btCore (chg_bds))
00159 infeasible = true;
00160 else {
00161
00162 const double
00163 *lb = solver -> getColLower (),
00164 *ub = solver -> getColUpper ();
00165
00166
00167 estimate = CoinMax (0., problem_ -> Lb (objind) - lb [objind]);
00168
00169
00170
00171
00172 for (int i=0; i<nvars; i++) {
00173 if (problem_ -> Lb (i) > lb [i]) solver -> setColLower (i, problem_ -> Lb (i));
00174 if (problem_ -> Ub (i) < ub [i]) solver -> setColUpper (i, problem_ -> Ub (i));
00175 }
00176 }
00177 }
00178
00179 if (!infeasible && doConvCuts_ && simulate_ && cutGen_) {
00180
00181
00182 int nchanged, *changed = NULL;
00183 OsiCuts cs;
00184
00185
00186 sparse2dense (nvars, chg_bds, changed, nchanged);
00187 cutGen_ -> genRowCuts (*solver, cs, nchanged, changed, chg_bds);
00188 free (changed);
00189
00190 solver -> applyCuts (cs);
00191 }
00192
00193 delete [] chg_bds;
00194
00195 problem_ -> domain () -> pop ();
00196 }
00197
00198
00199 branchIndex_++;
00200
00201 return (infeasible ? COIN_DBL_MAX : estimate);
00202 }