00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CouenneObject.hpp"
00012 #include "CouenneBranchingObject.hpp"
00013 #include "CouenneProblem.hpp"
00014
00015 using namespace Ipopt;
00016 using namespace Couenne;
00017
00018
00019 int CouenneBranchingObject::nOrbBr = 0;
00020 int CouenneBranchingObject::maxDepthOrbBranch = -1;
00021 int CouenneBranchingObject::nSGcomputations = 0;
00022
00023 #define OB_WEIGHT 0.6
00024
00029 void CouenneBranchingObject::branchCore (OsiSolverInterface *solver, int indVar, int way, bool integer, double brpt,
00030 t_chg_bounds *&chg_bds) {
00035
00036
00037 if ((doFBBT_ && problem_ -> doFBBT ()) ||
00038 (doConvCuts_ && simulate_ && cutGen_))
00039 chg_bds = new t_chg_bounds [problem_ -> nVars ()];
00040
00041 #ifdef COIN_HAS_NTY
00042
00043 if (problem_ -> orbitalBranching ()) {
00044
00045
00046
00047
00048
00049
00050
00051
00052 if (!way) {
00053
00054
00055
00056 std::vector< int > *branch_orbit = problem_ -> Find_Orbit (indVar);
00057
00058 double
00059 lb = solver -> getColLower () [indVar],
00060 ub = solver -> getColUpper () [indVar],
00061 ob_brpt = lb + (ub-lb) / (branch_orbit -> size () + 1),
00062 OB_weight = OB_WEIGHT;
00063
00064 brpt = OB_weight * ob_brpt + (1-OB_weight) * brpt;
00065
00066 if (jnlst_ -> ProduceOutput (J_ERROR, J_BRANCHING)) {
00067
00068 printf ("Branch: x%d <= %g [%g,%g]\n",
00069 indVar,
00070 integer ? floor (brpt) : brpt,
00071 solver -> getColLower () [indVar],
00072 solver -> getColUpper () [indVar]);
00073
00074 if (problem_ -> bestSol ()) {
00075
00076 if ((solver -> getColUpper () [indVar] > problem_ -> bestSol () [indVar]) &&
00077 (brpt < problem_ -> bestSol () [indVar]))
00078
00079 printf ("Branching rule EXCLUDES optimal solution\n");
00080 else
00081 for (int i=0; i<problem_ -> nVars (); i++)
00082
00083 if ((solver -> getColLower () [indVar] > problem_ -> bestSol () [indVar] + COUENNE_EPS) ||
00084 (solver -> getColUpper () [indVar] < problem_ -> bestSol () [indVar] - COUENNE_EPS))
00085
00086 {printf ("This node does not include optimal solution\n"); break;}
00087 }
00088 }
00089
00090
00091
00092
00093
00094 solver -> setColUpper (indVar, integer ? floor (brpt) : brpt);
00095
00096 if (!simulate_ && (problem_ -> orbitalBranching ())){
00097
00098
00099
00100 problem_ -> ChangeBounds (solver -> getColLower (),
00101 solver -> getColUpper (),
00102 problem_ -> nVars ());
00103
00104 problem_ -> Compute_Symmetry ();
00105
00106 }
00107
00108 if (chg_bds) chg_bds [indVar].setUpper (t_chg_bounds::CHANGED);
00109
00110
00111
00112
00113
00114
00115
00116 }
00117 else {
00118
00119
00120
00121 if (!simulate_ && (problem_ -> orbitalBranching ())){
00122
00123 problem_ -> ChangeBounds (solver -> getColLower (),
00124 solver -> getColUpper (),
00125 problem_ -> nVars ());
00126
00127 problem_ -> Compute_Symmetry ();
00128
00129 }
00130
00131 std::vector< int > *branch_orbit = problem_ -> Find_Orbit (indVar);
00132
00133 jnlst_ -> Printf (J_ERROR, J_BRANCHING, "Branch Symm (%d vars):", branch_orbit -> size ());
00134
00135 if (!simulate_ && (branch_orbit -> size () > 1))
00136 nOrbBr ++;
00137
00138 bool
00139 brExclude = false,
00140 nodeExclude = false;
00141
00142 double
00143 lb = solver -> getColLower () [indVar],
00144 ub = solver -> getColUpper () [indVar],
00145 ob_brpt = lb + (ub-lb) / ((double) branch_orbit -> size () + 1),
00146 OB_weight = OB_WEIGHT;
00147
00148
00149
00150 brpt = OB_weight * ob_brpt + (1-OB_weight) * brpt;
00151
00152 for (std::vector<int>::iterator it = branch_orbit -> begin (); it != branch_orbit -> end (); ++it) {
00153 assert (*it < problem_ -> nVars ());
00154
00155
00156
00157 if (jnlst_ -> ProduceOutput (J_ERROR, J_BRANCHING)) {
00158 printf (" x%d>%g [%g,%g]",
00159 *it,
00160 integer ? ceil (brpt) : brpt,
00161 solver -> getColLower () [*it],
00162 solver -> getColUpper () [*it]);
00163
00164 if (problem_ -> bestSol () &&
00165 (solver -> getColLower () [*it] < problem_ -> bestSol () [*it]) &&
00166 (brpt > problem_ -> bestSol () [*it]) && !brExclude)
00167
00168 brExclude = true;
00169
00170 if (problem_ -> bestSol ()) {
00171
00172 for (int i=0; i<problem_ -> nVars (); i++)
00173
00174 if (((solver -> getColLower () [indVar] > problem_ -> bestSol () [indVar] + COUENNE_EPS) ||
00175 (solver -> getColUpper () [indVar] < problem_ -> bestSol () [indVar] - COUENNE_EPS))) {
00176
00177 nodeExclude = true;
00178 break;
00179 }
00180 }
00181 }
00182
00183
00184 if ((integer ? ceil (brpt) : brpt) > solver -> getColLower () [*it]) {
00185
00186 solver -> setColLower (*it, integer ? ceil (brpt) : brpt);
00187 if (chg_bds) chg_bds [*it].setLower (t_chg_bounds::CHANGED);
00188 }
00189 }
00190
00191 if (jnlst_ -> ProduceOutput (J_ERROR, J_BRANCHING)) {
00192 if (brExclude) printf (" (Branching EXCLUDES optimal solution)");
00193 if (nodeExclude) printf (" (This node does not contain optimal solution)");
00194 printf ("\n");
00195 }
00196
00197 delete branch_orbit;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206 return;
00207 }
00208
00209 #endif
00210
00212
00213 if (!way) {
00214
00215 if (jnlst_ -> ProduceOutput (J_ERROR, J_BRANCHING)) {
00216
00217 printf ("Branch: x%d <= %g [%g,%g] (opt %g)\n",
00218 indVar,
00219 integer ? floor (brpt) : brpt,
00220 solver -> getColLower () [indVar],
00221 solver -> getColUpper () [indVar],
00222 problem_ -> bestSol () ? problem_ -> bestSol () [indVar] : 0.);
00223
00224 if (problem_ -> bestSol ()) {
00225
00226 if ((solver -> getColUpper () [indVar] >= problem_ -> bestSol () [indVar]) &&
00227 (brpt < problem_ -> bestSol () [indVar]))
00228
00229 printf ("Branching EXCLUDES optimal solution\n");
00230 else
00231 for (int i=0; i<problem_ -> nVars (); i++)
00232
00233 if ((solver -> getColLower () [i] > problem_ -> bestSol () [i] + COUENNE_EPS) ||
00234 (solver -> getColUpper () [i] < problem_ -> bestSol () [i] - COUENNE_EPS))
00235
00236 {printf ("This node does not contain optimal solution: x%d in [%g,%g] (%g)\n",
00237 i, solver -> getColLower () [i], solver -> getColUpper () [i], problem_ -> bestSol () [i]); break;}
00238 }
00239 }
00240
00241
00242 solver -> setColUpper (indVar, integer ? floor (brpt + COUENNE_EPS) : brpt);
00243 assert (solver -> getColUpper () [indVar] <= brpt + COUENNE_EPS);
00244 if (chg_bds) chg_bds [indVar].setUpper (t_chg_bounds::CHANGED);
00245
00246 } else {
00247
00248 if (jnlst_ -> ProduceOutput (J_ERROR, J_BRANCHING)) {
00249
00250 printf ("Branch: x%d >= %g [%g,%g] (opt %g)\n",
00251 indVar,
00252 integer ? ceil (brpt) : brpt,
00253 solver -> getColLower () [indVar],
00254 solver -> getColUpper () [indVar],
00255 problem_ -> bestSol () ? problem_ -> bestSol () [indVar] : 0.);
00256
00257 if (problem_ -> bestSol ()) {
00258
00259 if ((solver -> getColLower () [indVar] <= problem_ -> bestSol () [indVar]) &&
00260 (brpt > problem_ -> bestSol () [indVar]))
00261
00262 printf ("Branching EXCLUDES optimal solution\n");
00263
00264 else
00265 for (int i=0; i<problem_ -> nVars (); i++)
00266
00267 if ((solver -> getColLower () [indVar] > problem_ -> bestSol () [indVar] + COUENNE_EPS) ||
00268 (solver -> getColUpper () [indVar] < problem_ -> bestSol () [indVar] - COUENNE_EPS))
00269
00270 {printf ("This node does not contain optimal solution: x%d in [%g,%g] (%g)\n",
00271 i, solver -> getColLower () [i], solver -> getColUpper () [i], problem_ -> bestSol () [i]); break;}
00272 }
00273 }
00274
00275
00276 solver -> setColLower (indVar, integer ? ceil (brpt - COUENNE_EPS) : brpt);
00277 if (chg_bds) chg_bds [indVar].setLower (t_chg_bounds::CHANGED);
00278 }
00279 }