00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "CoinTime.hpp"
00013 #include "CouenneChooseStrong.hpp"
00014 #include "CouenneProblem.hpp"
00015 #include "CouenneBranchingObject.hpp"
00016 #include "CouenneSolverInterface.hpp"
00017
00020 double distance (const double *p1, const double *p2, int size, double k=2.) {
00021
00022 double
00023 result = 0.,
00024 element;
00025
00026 if (k == 2.)
00027
00028 while (size--) {
00029 element = *p1++ - *p2++;
00030 result += element * element;
00031 }
00032
00033 else
00034
00035 while (size--) {
00036 element = *p1++ - *p2++;
00037 result += pow (element, k);
00038 }
00039
00040 return pow (result, 1. / k);
00041 }
00042
00043
00044
00045
00058 int CouenneChooseStrong::doStrongBranching (CouenneSolverInterface * solver,
00059 OsiBranchingInformation *info,
00060 int numberToDo, int returnCriterion) {
00061
00062 jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING,
00063 "\n-\n------- CCS: trying %d objects:\n", numberToDo);
00064
00065 solver -> doingResolve () = false;
00066
00067 int numberColumns = solver -> getNumCols ();
00068
00069 solver -> markHotStart ();
00070
00071 const double
00072 *lower = info -> lower_,
00073 *upper = info -> upper_;
00074
00075 double
00076 *saveLower = CoinCopyOfArray (info -> lower_, numberColumns),
00077 *saveUpper = CoinCopyOfArray (info -> upper_, numberColumns),
00078 *Lower0 = CoinCopyOfArray (info -> lower_, numberColumns),
00079 *Upper0 = CoinCopyOfArray (info -> upper_, numberColumns),
00080 *oldLower = new double [numberColumns],
00081 *oldUpper = new double [numberColumns],
00082 *lpSol = NULL,
00083 timeStart = CoinCpuTime ();
00084
00085
00086 if (pseudoUpdateLP_)
00087 lpSol = CoinCopyOfArray (info -> solution_, numberColumns);
00088
00089
00090 problem_ -> domain () -> push
00091 (problem_ -> nVars (),
00092 info -> solution_,
00093 info -> lower_,
00094 info -> upper_);
00095
00096 int returnCode = 0, iDo = 0;
00097
00098 for (;iDo < numberToDo; iDo++) {
00099
00100 Bonmin::HotInfo * result = results_ () + iDo;
00101
00102 OsiObject *Object = solver_ -> objects () [result -> whichObject ()];
00103 CouenneObject *CouObj = dynamic_cast <CouenneObject *> (Object);
00104
00105
00106 OsiBranchingObject * branch = result -> branchingObject ();
00107 assert (branch->numberBranches()==2);
00108
00109 CouenneBranchingObject *cb = dynamic_cast <CouenneBranchingObject *> (branch);
00110 if (cb) cb -> setSimulate (true);
00111
00112
00113
00114
00115
00116 int
00117 status0 = -1,
00118 status1 = -1;
00119
00120 OsiSolverInterface * thisSolver = solver;
00121
00122
00123
00124 if (branch -> boundBranch ()) {
00125
00126 if (branch -> branch (solver) > COUENNE_INFINITY)
00127 result -> setDownStatus (status0 = 1);
00128
00129 else {
00130
00131 bool infeasible = false;
00132
00133
00134 if (!CouObj) {
00135
00136 int
00137 indVar = Object -> columnNumber (),
00138 nvars = problem_ -> nVars ();
00139
00140 t_chg_bounds *chg_bds = new t_chg_bounds [nvars];
00141
00142 chg_bds [indVar].setUpper (t_chg_bounds::CHANGED);
00143
00144 if (problem_ -> doFBBT ()) {
00145
00146 problem_ -> installCutOff ();
00147
00148 if (!problem_ -> btCore (chg_bds))
00149 infeasible = true;
00150
00151 else {
00152 const double
00153 *lb = solver -> getColLower (),
00154 *ub = solver -> getColUpper ();
00155
00156 for (int i=0; i<nvars; i++) {
00157 if (problem_ -> Lb (i) > lb [i]) solver -> setColLower (i, problem_ -> Lb (i));
00158 if (problem_ -> Ub (i) < ub [i]) solver -> setColUpper (i, problem_ -> Ub (i));
00159 }
00160 }
00161 }
00162
00163 delete [] chg_bds;
00164 }
00165
00166 if (infeasible) result -> setDownStatus (status0 = 1);
00167 else {
00168 solver -> solveFromHotStart ();
00169
00170
00171 if (pseudoUpdateLP_ && CouObj && solver -> isProvenOptimal ()) {
00172 CouNumber dist = distance (lpSol, solver -> getColSolution (), numberColumns);
00173 if (dist > COUENNE_EPS)
00174 CouObj -> setEstimate (dist, 0);
00175 }
00176 }
00177 }
00178
00179 } else {
00180
00181
00182 thisSolver = solver -> clone ();
00183
00184 if (branch -> branch (thisSolver) > COUENNE_INFINITY)
00185 result -> setDownStatus (status0 = 1);
00186
00187 else {
00188 int limit;
00189 thisSolver -> getIntParam (OsiMaxNumIterationHotStart, limit);
00190 thisSolver -> setIntParam (OsiMaxNumIteration, limit);
00191
00192 thisSolver -> resolve ();
00193 if (pseudoUpdateLP_ && CouObj && thisSolver -> isProvenOptimal ()) {
00194 CouNumber dist = distance (lpSol, thisSolver -> getColSolution (), numberColumns);
00195 if (dist > COUENNE_EPS)
00196 CouObj -> setEstimate (dist, 0);
00197 }
00198 }
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 if (status0 < 0)
00211 status0 = result -> updateInformation (thisSolver, info, this);
00212
00213 numberStrongIterations_ += thisSolver -> getIterationCount();
00214
00215 if ((status0 == 3) && (trustStrongForSolution_)) {
00216
00217 info -> cutoff_ = goodObjectiveValue_;
00218 problem_ -> setCutOff (goodObjectiveValue_);
00219 status0 = 0;
00220 }
00221
00222 if (solver != thisSolver)
00223 delete thisSolver;
00224
00225
00226
00227 CoinCopyN (problem_ -> Lb (), numberColumns, oldLower);
00228 CoinCopyN (problem_ -> Ub (), numberColumns, oldUpper);
00229
00230
00231 for (int j=0; j<numberColumns; j++) {
00232
00233 if (saveLower [j] != lower [j]) solver -> setColLower (j, saveLower [j]);
00234 if (saveUpper [j] != upper [j]) solver -> setColUpper (j, saveUpper [j]);
00235 }
00236
00237
00238
00239 thisSolver = solver;
00240
00241 if (branch -> boundBranch ()) {
00242
00243 if (branch -> branch (solver) > COUENNE_INFINITY)
00244 result -> setUpStatus (status1 = 1);
00245
00246 else {
00247
00248 bool infeasible = false;
00249
00250
00251 if (!CouObj) {
00252
00253 int
00254 indVar = Object -> columnNumber (),
00255 nvars = problem_ -> nVars ();
00256
00257 t_chg_bounds *chg_bds = new t_chg_bounds [nvars];
00258
00259 chg_bds [indVar].setLower (t_chg_bounds::CHANGED);
00260
00261 if (problem_ -> doFBBT ()) {
00262
00263 problem_ -> installCutOff ();
00264
00265 if (!problem_ -> btCore (chg_bds))
00266 infeasible = true;
00267
00268 else {
00269 const double
00270 *lb = solver -> getColLower (),
00271 *ub = solver -> getColUpper ();
00272
00273 for (int i=0; i<nvars; i++) {
00274 if (problem_ -> Lb (i) > lb [i]) solver -> setColLower (i, problem_ -> Lb (i));
00275 if (problem_ -> Ub (i) < ub [i]) solver -> setColUpper (i, problem_ -> Ub (i));
00276 }
00277 }
00278 }
00279
00280 delete [] chg_bds;
00281 }
00282
00283 if (infeasible) result -> setUpStatus (status0 = 1);
00284 else {
00285
00286 solver -> solveFromHotStart ();
00287
00288 if (pseudoUpdateLP_ && CouObj && solver -> isProvenOptimal ()) {
00289 CouNumber dist = distance (lpSol, solver -> getColSolution (), numberColumns);
00290 if (dist > COUENNE_EPS)
00291 CouObj -> setEstimate (dist, 1);
00292 }
00293 }
00294 }
00295 } else {
00296
00297 thisSolver = solver -> clone ();
00298
00299 if (branch -> branch (thisSolver) > COUENNE_INFINITY)
00300 result -> setUpStatus (status1 = 1);
00301
00302 else {
00303
00304 int limit;
00305 thisSolver -> getIntParam (OsiMaxNumIterationHotStart, limit);
00306 thisSolver -> setIntParam (OsiMaxNumIteration, limit);
00307
00308 thisSolver -> resolve();
00309 if (pseudoUpdateLP_ && CouObj && thisSolver -> isProvenOptimal ()) {
00310 CouNumber dist = distance (lpSol, thisSolver -> getColSolution (), numberColumns);
00311 if (dist > COUENNE_EPS)
00312 CouObj -> setEstimate (dist, 1);
00313 }
00314 }
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 if (status1 < 0)
00327 status1 = result -> updateInformation (thisSolver, info, this);
00328
00329 numberStrongDone_++;
00330 numberStrongIterations_ += thisSolver->getIterationCount();
00331
00332 if ((status1 == 3) && (trustStrongForSolution_)) {
00333
00334 info -> cutoff_ = goodObjectiveValue_;
00335 problem_ -> setCutOff (goodObjectiveValue_);
00336 status1 = 0;
00337 }
00338
00339 jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING, "-------\n");
00340
00341 if (cb) cb -> setSimulate (false);
00342
00344
00345 if (solver != thisSolver)
00346 delete thisSolver;
00347
00348 bool tightened = false;
00349
00350 t_chg_bounds *chg_bds = new t_chg_bounds [numberColumns];
00351
00352
00353 for (int j=0; j<numberColumns; j++) {
00354
00355 if (oldLower [j] < problem_ -> Lb (j)) problem_ -> Lb (j) = oldLower [j];
00356 if (oldUpper [j] > problem_ -> Ub (j)) problem_ -> Ub (j) = oldUpper [j];
00357
00358 if (problem_ -> Lb (j) > lower [j] + COUENNE_EPS) {
00359 chg_bds [j].setLower (t_chg_bounds::CHANGED);
00360 tightened = true;
00361 }
00362
00363 if (problem_ -> Ub (j) < upper [j] - COUENNE_EPS) {
00364 chg_bds [j].setUpper (t_chg_bounds::CHANGED);
00365 tightened = true;
00366 }
00367 }
00368
00369 if (tightened &&
00370 (problem_ -> doFBBT ()) &&
00371 !(problem_ -> btCore (chg_bds)))
00372
00373 status0 = status1 = 1;
00374
00375 delete [] chg_bds;
00376
00377
00378 for (int j=0; j<numberColumns; j++) {
00379
00380 if (oldLower [j] < problem_ -> Lb (j)) problem_ -> Lb (j) = oldLower [j];
00381 if (oldUpper [j] > problem_ -> Ub (j)) problem_ -> Ub (j) = oldUpper [j];
00382 }
00383
00384
00385
00386 for (int j=0; j<numberColumns; j++) {
00387
00388 solver -> setColLower (j, saveLower [j] = problem_ -> Lb (j));
00389 solver -> setColUpper (j, saveUpper [j] = problem_ -> Ub (j));
00390 }
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 if (status0 == 1 &&
00408 status1 == 1) {
00409 returnCode=-1;
00410 break;
00411 } else if (status0==1 || status1==1) {
00412 numberStrongFixed_++;
00413 if (!returnCriterion) {
00414 returnCode=1;
00415 } else {
00416 returnCode=2;
00417 break;
00418 }
00419 }
00420
00421 bool hitMaxTime = ( CoinCpuTime()-timeStart > info->timeRemaining_);
00422 if (hitMaxTime) {
00423 returnCode=3;
00424 break;
00425 }
00426 }
00427
00428
00429 if (jnlst_ -> ProduceOutput (J_DETAILED, J_BRANCHING)) {
00430 printf ("tightened bounds: ");
00431
00432 for (int j=0; j<numberColumns; j++) {
00433
00434 if (problem_ -> Lb (j) > Lower0 [j]) printf ("l%d (%g-->%g) ", j,Lower0[j], problem_->Lb (j));
00435 if (problem_ -> Ub (j) < Upper0 [j]) printf ("u%d (%g-->%g) ", j,Upper0[j], problem_->Ub (j));
00436 }
00437 }
00438
00439 delete [] Lower0;
00440 delete [] Upper0;
00441
00442 problem_ -> domain () -> pop ();
00443
00444 delete [] lpSol;
00445
00446 jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING, "----------------------done\n\n\n");
00447
00448 if (iDo < numberToDo) iDo++;
00449 assert (iDo <= (int) results_.size());
00450 results_.resize (iDo);
00451
00452 delete [] oldLower;
00453 delete [] oldUpper;
00454
00455 delete [] saveLower;
00456 delete [] saveUpper;
00457
00458 solver -> unmarkHotStart ();
00459
00460 solver -> doingResolve () = true;
00461
00462 return returnCode;
00463 }
00464