00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "BonCbc.hpp"
00012 #include "BonOACutGenerator2.hpp"
00013 #include "BonCbcNlpStrategy.hpp"
00014 #include "BonBabInfos.hpp"
00015 #include "CbcModel.hpp"
00016 #include "CbcBranchActual.hpp"
00017 #include "CbcCutGenerator.hpp"
00018 #include "CbcCompareActual.hpp"
00019 #include "CbcCompareObjective.hpp"
00020 #include "CbcCompareEstimate.hpp"
00021
00022 #include "BonExitCodes.hpp"
00023
00024 #include "BonChooseVariable.hpp"
00025 #include "BonGuessHeuristic.hpp"
00026
00027 #include "BonDiver.hpp"
00028 #include "BonLinearCutsGenerator.hpp"
00029 #include "BonTMINLPLinObj.hpp"
00030
00031 #include "CouenneBab.hpp"
00032 #include "CouenneProblem.hpp"
00033 #include "CouenneRecordBestSol.hpp"
00034
00035
00036 #define CUTOFF_TOL 1e-6
00037
00038
00039 static CbcModel * currentBranchModel = NULL;
00040 extern Bonmin::OACutGenerator2 * currentOA;
00041 extern CbcModel * OAModel;
00042
00043 #define SIGNAL
00044 #ifdef SIGNAL
00045 #include "CoinSignal.hpp"
00046
00047 extern "C" {
00048
00049 static bool BonminInterruptedOnce = false;
00050
00051 static void couenne_signal_handler (int whichSignal) {
00052
00053 if (BonminInterruptedOnce) {
00054
00055 exit(0);
00056 }
00057 if (currentBranchModel) currentBranchModel->sayEventHappened();
00058 if (OAModel) OAModel->sayEventHappened();
00059 if (currentOA) currentOA->parameter().maxLocalSearchTime_ = 0.;
00060
00061 BonminInterruptedOnce = true;
00062 }
00063 }
00064 #endif
00065
00066 using namespace Couenne;
00067 using namespace Bonmin;
00068
00070 CouenneBab::CouenneBab ():
00071
00072 Bab (),
00073 problem_(NULL)
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 {}
00087
00088
00090 CouenneBab::~CouenneBab () {
00091
00092
00093
00094
00095
00096
00097
00098
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 void CouenneBab::setProblem (CouenneProblem *p)
00110 {problem_ = p;}
00111
00112
00114 void CouenneBab::branchAndBound (Bonmin::BabSetupBase & s) {
00115
00116 double remaining_time = s.getDoubleParameter(Bonmin::BabSetupBase::MaxTime) + CoinCpuTime();
00117
00118 OsiBabSolver * babInfo = dynamic_cast<OsiBabSolver *>(s.continuousSolver()->getAuxiliaryInfo());
00119 assert(babInfo);
00120 Bonmin::BabInfo * bonBabInfoPtr = dynamic_cast<Bonmin::BabInfo*>(babInfo);
00121 if (bonBabInfoPtr == NULL) {
00122 bonBabInfoPtr = new Bonmin::BabInfo(*babInfo);
00123 s.continuousSolver()->setAuxiliaryInfo(bonBabInfoPtr);
00124 delete bonBabInfoPtr;
00125 bonBabInfoPtr = dynamic_cast<Bonmin::BabInfo*>(s.continuousSolver()->getAuxiliaryInfo());
00126 }
00127 bonBabInfoPtr->setBabPtr(this);
00128
00129 s.nonlinearSolver()->solver()->setup_global_time_limit(s.getDoubleParameter(Bonmin::BabSetupBase::MaxTime));
00130 OsiSolverInterface * solver = s.continuousSolver()->clone();
00131 delete modelHandler_;
00132 modelHandler_ = s.continuousSolver()->messageHandler()->clone();
00133 model_.passInMessageHandler(modelHandler_);
00134 model_.assignSolver(solver, true);
00135
00136
00137
00138
00139
00140
00141 int specOpt = s.getIntParameter(Bonmin::BabSetupBase::SpecialOption);
00142 if (specOpt) {
00143 model_.setSpecialOptions(specOpt);
00144 if (specOpt==16) {
00145 Bonmin::CbcNlpStrategy strat(s.getIntParameter(Bonmin::BabSetupBase::MaxFailures),
00146 s.getIntParameter(Bonmin::BabSetupBase::MaxInfeasible),
00147 s.getIntParameter(Bonmin::BabSetupBase::FailureBehavior));
00148 model_.setStrategy(strat);
00149 }
00150 }
00151
00152 model_.setMaximumCutPasses(s.getIntParameter(Bonmin::BabSetupBase::NumCutPasses));
00153 model_.setMaximumCutPassesAtRoot(s.getIntParameter(Bonmin::BabSetupBase::NumCutPassesAtRoot));
00154
00155
00156 for (Bonmin::BabSetupBase::CuttingMethods::iterator i = s.cutGenerators().begin() ;
00157 i != s.cutGenerators().end() ; i++) {
00158
00159 Bonmin::OaDecompositionBase * oa = dynamic_cast<Bonmin::OaDecompositionBase *>(i->cgl);
00160 if (oa && oa->reassignLpsolver())
00161 oa->assignLpInterface(model_.solver());
00162 model_.addCutGenerator(i->cgl,i->frequency,i->id.c_str(), i->normal,
00163 i->atSolution);
00164 if(i->always){
00165 model_.cutGenerators()[model_.numberCutGenerators()-1]
00166 ->setMustCallAgain(true);
00167 }
00168 }
00169
00170 for (Bonmin::BabSetupBase::HeuristicMethods::iterator i = s.heuristics().begin() ;
00171 i != s.heuristics().end() ; i++) {
00172 CbcHeuristic * heu = i->heuristic;
00173 heu->setModel(&model_);
00174 model_.addHeuristic(heu, i->id.c_str());
00175 }
00176
00177
00178 int logLevel = s.continuousSolver()->messageHandler()->logLevel();
00179
00180
00181 model_.setLogLevel(s.getIntParameter(Bonmin::BabSetupBase::BabLogLevel));
00182
00183
00184 model_.solver()->messageHandler()->setLogLevel(logLevel);
00185
00186 model_.setPrintFrequency(s.getIntParameter(Bonmin::BabSetupBase::BabLogInterval));
00187
00188 bool ChangedObject = false;
00189
00190 if (s.continuousSolver()->objects()==NULL) {
00191
00192 const OsiTMINLPInterface * nlpSolver = s.nonlinearSolver();
00193
00194 const int * priorities = nlpSolver->getPriorities();
00195 const double * upPsCosts = nlpSolver->getUpPsCosts();
00196 const double * downPsCosts = nlpSolver->getDownPsCosts();
00197 const int * directions = nlpSolver->getBranchingDirections();
00198 bool hasPseudo = (upPsCosts!=NULL);
00199 model_.findIntegers(true,hasPseudo);
00200 OsiObject ** simpleIntegerObjects = model_.objects();
00201 int numberObjects = model_.numberObjects();
00202 if (priorities != NULL || directions != NULL || hasPseudo) {
00203 ChangedObject = true;
00204 for (int i = 0 ; i < numberObjects ; i++) {
00205 CbcObject * object = dynamic_cast<CbcObject *>
00206 (simpleIntegerObjects[i]);
00207 int iCol = object->columnNumber();
00208 if (priorities)
00209 object->setPriority(priorities[iCol]);
00210 if (directions)
00211 object->setPreferredWay(directions[iCol]);
00212 if (upPsCosts) {
00213 CbcSimpleIntegerPseudoCost * pscObject =
00214 dynamic_cast<CbcSimpleIntegerPseudoCost*> (object);
00215 pscObject->setUpPseudoCost(upPsCosts[iCol]);
00216 pscObject->setDownPseudoCost(downPsCosts[iCol]);
00217 }
00218 }
00219 }
00220
00221 #if 1
00222
00223 const TMINLP::SosInfo * sos = s.nonlinearSolver()->model()->sosConstraints();
00224 if (!s.getIntParameter(Bonmin::BabSetupBase::DisableSos) && sos && sos->num > 0)
00225
00226 {
00227 const OsiTMINLPInterface * nlpSolver = s.nonlinearSolver();
00228 const int & numSos = sos->num;
00229 (*nlpSolver->messageHandler())<<"Adding "<<sos->num<<" sos constraints."
00230 <<CoinMessageEol;
00231
00232 CbcObject ** objects = new CbcObject*[numSos];
00233 const int * starts = sos->starts;
00234 const int * indices = sos->indices;
00235 const char * types = sos->types;
00236 const double * weights = sos->weights;
00237
00238 bool hasPriorities = false;
00239 const int * varPriorities = nlpSolver->getPriorities();
00240 int numberObjects = model_.numberObjects();
00241 if (varPriorities)
00242 {
00243 for (int i = 0 ; i < numberObjects ; i++) {
00244 if (varPriorities[i]) {
00245 hasPriorities = true;
00246 break;
00247 }
00248 }
00249 }
00250 const int * sosPriorities = sos->priorities;
00251 if (sosPriorities)
00252 {
00253 for (int i = 0 ; i < numSos ; i++) {
00254 if (sosPriorities[i]) {
00255 hasPriorities = true;
00256 break;
00257 }
00258 }
00259 }
00260 for (int i = 0 ; i < numSos ; i++)
00261 {
00262 int start = starts[i];
00263 int length = starts[i + 1] - start;
00264 #ifdef DO_IT_NWAY
00265 printf("setting nway object\n"),
00266 objects[i] = new CbcNWay(&model_, length, &indices[start],
00267 i);
00268 objects[i]->setPriority(1);
00269 #else
00270 objects[i] = new CbcSOS(&model_, length, &indices[start],
00271 &weights[start], i, types[i]);
00272 objects[i]->setPriority(10);
00273 #endif
00274 if (hasPriorities && sosPriorities && sosPriorities[i]) {
00275 objects[i]->setPriority(sosPriorities[i]);
00276 }
00277 }
00278 model_.addObjects(numSos, objects);
00279 for (int i = 0 ; i < numSos ; i++)
00280 delete objects[i];
00281 delete [] objects;
00282 }
00283 #endif
00284
00285 if (s.objects().size()) {
00286 CbcObject ** objects = new CbcObject *[s.objects().size()];
00287 for (unsigned int i = 0 ; i < s.objects().size() ; i++) {
00288 objects[i] = dynamic_cast<CbcObject *> (s.objects()[i]);
00289 assert(objects[i]);
00290 objects[i]->setModel(&model_);
00291 }
00292 model_.addObjects(s.objects().size(), objects);
00293 delete [] objects;
00294 }
00295
00296 replaceIntegers(model_.objects(), model_.numberObjects());
00297 }
00298 else {
00299
00300 assert (s.branchingMethod() != NULL);
00301
00302
00303
00304
00305
00306
00307 int nco = s.continuousSolver () -> numberObjects ();
00308 OsiObject **objs = new OsiObject * [nco];
00309 for (int i=0; i<nco; i++)
00310 objs [i] = s.continuousSolver () -> objects () [i];
00311 model_.addObjects (nco, objs);
00312 delete [] objs;
00313
00314
00315 CbcBranchDefaultDecision branch;
00316 s.branchingMethod()->setSolver(model_.solver());
00317 BonChooseVariable * strong2 = dynamic_cast<BonChooseVariable *>(s.branchingMethod());
00318 if (strong2)
00319 strong2->setCbcModel(&model_);
00320 branch.setChooseMethod(*s.branchingMethod());
00321
00322 model_.setBranchingMethod(&branch);
00323
00324 model_.solver()->deleteObjects();
00325 }
00326
00327 model_.setDblParam(CbcModel::CbcCutoffIncrement, s.getDoubleParameter(Bonmin::BabSetupBase::CutoffDecr));
00328
00329 model_.setCutoff(s.getDoubleParameter(Bonmin::BabSetupBase::Cutoff) + CUTOFF_TOL);
00330
00331 model_.setDblParam(CbcModel::CbcAllowableGap, s.getDoubleParameter(Bonmin::BabSetupBase::AllowableGap));
00332 model_.setDblParam(CbcModel::CbcAllowableFractionGap, s.getDoubleParameter(Bonmin::BabSetupBase::AllowableFractionGap));
00333
00334
00335
00336 if (s.nodeComparisonMethod()==Bonmin::BabSetupBase::bestBound) {
00337 CbcCompareObjective compare;
00338 model_.setNodeComparison(compare);
00339 }
00340 else if (s.nodeComparisonMethod()==Bonmin::BabSetupBase::DFS) {
00341 CbcCompareDepth compare;
00342 model_.setNodeComparison(compare);
00343 }
00344 else if (s.nodeComparisonMethod()==Bonmin::BabSetupBase::BFS) {
00345 CbcCompareDefault compare;
00346 compare.setWeight(0.0);
00347 model_.setNodeComparison(compare);
00348 }
00349 else if (s.nodeComparisonMethod()==Bonmin::BabSetupBase::dynamic) {
00350 CbcCompareDefault compare;
00351 model_.setNodeComparison(compare);
00352 }
00353 else if (s.nodeComparisonMethod()==Bonmin::BabSetupBase::bestGuess) {
00354
00355
00356 CbcCompareEstimate compare;
00357 model_.setNodeComparison(compare);
00358 GuessHeuristic * guessHeu = new GuessHeuristic(model_);
00359 model_.addHeuristic(guessHeu);
00360 delete guessHeu;
00361 }
00362
00363 if (s.treeTraversalMethod() == Bonmin::BabSetupBase::HeapOnly) {
00364
00365 }
00366 else if (s.treeTraversalMethod() == Bonmin::BabSetupBase::DiveFromBest) {
00367 CbcDiver treeTraversal;
00368 treeTraversal.initialize(s);
00369 model_.passInTreeHandler(treeTraversal);
00370 }
00371 else if (s.treeTraversalMethod() == Bonmin::BabSetupBase::ProbedDive) {
00372 CbcProbedDiver treeTraversal;
00373 treeTraversal.initialize(s);
00374 model_.passInTreeHandler(treeTraversal);
00375 }
00376 else if (s.treeTraversalMethod() == Bonmin::BabSetupBase::DfsDiveFromBest) {
00377 CbcDfsDiver treeTraversal;
00378 treeTraversal.initialize(s);
00379 model_.passInTreeHandler(treeTraversal);
00380 }
00381 else if (s.treeTraversalMethod() == Bonmin::BabSetupBase::DfsDiveDynamic) {
00382 CbcDfsDiver treeTraversal;
00383 treeTraversal.initialize(s);
00384 model_.passInTreeHandler(treeTraversal);
00385
00386 DiverCompare compare;
00387 compare.setComparisonDive(*model_.nodeComparison());
00388 compare.setComparisonBound(CbcCompareObjective());
00389 CbcDfsDiver * dfs = dynamic_cast<CbcDfsDiver *> (model_.tree());
00390 assert(dfs);
00391 compare.setDiver(dfs);
00392 model_.setNodeComparison(compare);
00393 }
00394
00395 model_.setNumberStrong(s.getIntParameter(Bonmin::BabSetupBase::NumberStrong));
00396 model_.setNumberBeforeTrust(s.getIntParameter(Bonmin::BabSetupBase::MinReliability));
00397 model_.setNumberPenalties(8);
00398
00399 model_.setDblParam(CbcModel::CbcMaximumSeconds, s.getDoubleParameter(Bonmin::BabSetupBase::MaxTime));
00400
00401 model_.setMaximumNodes(s.getIntParameter(Bonmin::BabSetupBase::MaxNodes));
00402
00403 model_.setMaximumNumberIterations(s.getIntParameter(Bonmin::BabSetupBase::MaxIterations));
00404
00405 model_.setMaximumSolutions(s.getIntParameter(Bonmin::BabSetupBase::MaxSolutions));
00406
00407 model_.setIntegerTolerance(s.getDoubleParameter(Bonmin::BabSetupBase::IntTol));
00408
00409
00410
00411 OsiObject ** objects = model_.objects();
00412 if (specOpt!=16 && objects) {
00413 int numberObjects = model_.numberObjects();
00414 if (objects_ != NULL) {
00415 for (int i = 0 ; i < nObjects_; i++)
00416 delete objects_[i];
00417 }
00418 delete [] objects_;
00419 objects_ = new OsiObject*[numberObjects];
00420 nObjects_ = numberObjects;
00421 for (int i = 0 ; i < numberObjects; i++) {
00422 OsiObject * obj = objects[i];
00423 CbcSimpleInteger * intObj = dynamic_cast<CbcSimpleInteger *> (obj);
00424 if (intObj) {
00425 objects_[i] = intObj->osiObject();
00426 }
00427 else {
00428 CbcSOS * sosObj = dynamic_cast<CbcSOS *>(obj);
00429 if (sosObj) objects_[i] = sosObj->osiObject(model_.solver());
00430 else {
00431 CbcObject * cbcObj = dynamic_cast<CbcObject *>(obj);
00432 if (cbcObj) {
00433 std::cerr<<"Unsupported CbcObject appears in the code"<<std::endl;
00434 throw UNSUPPORTED_CBC_OBJECT;
00435 }
00436 else {
00437 objects_[i]=obj->clone();
00438 }
00439 }
00440 }
00441 }
00442 CbcCutGenerator ** gen = model_.cutGenerators();
00443 int numGen = model_.numberCutGenerators();
00444 for (int i = 0 ; i < numGen ; i++) {
00445 Bonmin::OaDecompositionBase * oa = dynamic_cast<Bonmin::OaDecompositionBase * >(gen[i]->generator());
00446 if (oa)
00447 oa->setObjects(objects_,nObjects_);
00448 }
00449 }
00450
00451
00452 try {
00453
00454 {
00455 OsiTMINLPInterface * tmpOsi = NULL;
00456 if(s.nonlinearSolver() == s.continuousSolver()){
00457 tmpOsi = dynamic_cast<OsiTMINLPInterface *> (model_.solver());
00458 tmpOsi->forceSolverOutput(s.getIntParameter(Bonmin::BabSetupBase::RootLogLevel));
00459 }
00460 model_.initialSolve();
00461 if(tmpOsi != NULL){
00462 tmpOsi->setSolverOutputToDefault();
00463 }
00464 }
00465
00466 int ival;
00467 s.options()->GetEnumValue("enable_dynamic_nlp", ival, "bonmin.");
00468 if(s.nonlinearSolver() == s.continuousSolver() && ival)
00469 {
00470 if(!model_.solver()->isProvenOptimal() ){
00471
00472 OsiTMINLPInterface * tmpOsi = dynamic_cast<OsiTMINLPInterface *> (model_.solver());
00473 TMINLPLinObj * tmp_tminlp = dynamic_cast<TMINLPLinObj *> (tmpOsi->model());
00474 tmpOsi->setModel(tmp_tminlp->tminlp());
00475 model_.initialSolve();
00476 }
00477 else {
00478 LinearCutsGenerator cgl;
00479 cgl.initialize(s);
00480 OsiCuts cuts;
00481 cgl.generateCuts(*model_.solver(), cuts);
00482 std::vector<OsiRowCut *> mycuts(cuts.sizeRowCuts());
00483 for(int i = 0 ; i < cuts.sizeRowCuts() ; i++){
00484 mycuts[i] = cuts.rowCutPtr(i);
00485 }
00486 model_.solver()->applyRowCuts(mycuts.size(), (const OsiRowCut **) &mycuts[0]);
00487 }
00488
00489
00490 OsiTMINLPInterface * nlpSolver = dynamic_cast<OsiTMINLPInterface *>(model_.solver());
00491 if(nlpSolver && nlpSolver->getNewCutoffDecr()!=COIN_DBL_MAX)
00492 model_.setDblParam(CbcModel::CbcCutoffIncrement, nlpSolver->getNewCutoffDecr());
00493
00494 model_.solver()->resolve();
00495
00496 }
00497
00498
00499
00500 model_.passInSolverCharacteristics (bonBabInfoPtr);
00501
00502 continuousRelaxation_ =model_.solver()->getObjValue();
00503 if (specOpt==16)
00504 {
00505 #if 1
00506 const double * colsol = model_.solver()->getColSolution();
00507 const double * duals = model_.solver()->getRowPrice();
00508
00509 OsiTMINLPInterface * tnlpSolver = dynamic_cast<OsiTMINLPInterface *>(model_.solver());
00510
00511 if(tnlpSolver->problem()->has_x_init() != 2){
00512 model_.solver()->setColSolution(colsol);
00513 model_.solver()->setRowPrice(duals);
00514 }
00515 #else
00516 OsiTMINLPInterface * tnlpSolver = dynamic_cast<OsiTMINLPInterface *>(model_.solver());
00517 CoinWarmStart * warm = tnlpSolver->solver()->getWarmStart(tnlpSolver->problem());
00518 tnlpSolver->solver()->setWarmStart(warm, tnlpSolver->problem());
00519 delete warm;
00520 #endif
00521
00522 #if 0 // Sometimes primal dual point is problematic in the context of Cut-and-branch
00523 model_.solver()->resolve();
00524 if(!model_.solver()->isProvenOptimal())
00525 model_.solver()->setColSolution(NULL);
00526 #endif
00527 }
00528
00529 #ifdef SIGNAL
00530 CoinSighandler_t saveSignal = SIG_DFL;
00531
00532 saveSignal = signal (SIGINT,couenne_signal_handler);
00533 currentBranchModel = &model_;
00534 #endif
00535
00536
00537
00538
00539 remaining_time -= CoinCpuTime();
00540 model_.setDblParam(CbcModel::CbcMaximumSeconds, remaining_time);
00541 if(remaining_time > 0.)
00542 model_.branchAndBound();
00543 }
00544 catch(TNLPSolver::UnsolvedError *E){
00545 s.nonlinearSolver()->model()->finalize_solution(TMINLP::MINLP_ERROR,
00546 0,
00547 NULL,
00548 DBL_MAX);
00549 throw E;
00550
00551 }
00552 numNodes_ = model_.getNodeCount();
00553 bestObj_ = model_.getObjValue();
00554 bestBound_ = model_.getBestPossibleObjValue();
00555 mipIterationCount_ = model_.getIterationCount();
00556
00557 bool hasFailed = false;
00558 if (specOpt==16)
00559 {
00560 CbcNlpStrategy * nlpStrategy = dynamic_cast<CbcNlpStrategy *>(model_.strategy());
00561 if (nlpStrategy)
00562 hasFailed = nlpStrategy->hasFailed();
00563 else
00564 throw -1;
00565 }
00566 else
00567 hasFailed = s.nonlinearSolver()->hasContinuedOnAFailure();
00568
00569
00570
00571
00572 int numberGenerators = model_.numberCutGenerators();
00573 for (int iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
00574 CbcCutGenerator * generator = model_.cutGenerator(iGenerator);
00575
00576 if (true&&!(generator->numberCutsInTotal() || generator->numberColumnCuts()))
00577 continue;
00578 if(modelHandler_->logLevel() >= 1) {
00579 *modelHandler_ << generator->cutGeneratorName()
00580 << "was tried" << generator->numberTimesEntered()
00581 << "times and created" << generator->numberCutsInTotal()+generator->numberColumnCuts()
00582 << "cuts of which" << generator->numberCutsActive()
00583 << "were active after adding rounds of cuts";
00584
00585
00586
00587
00588
00589
00590
00591
00592 }
00593 }
00594
00595 TMINLP::SolverReturn status = TMINLP::MINLP_ERROR;
00596
00597 if (model_.numberObjects()==0) {
00598 if (bestSolution_)
00599 delete [] bestSolution_;
00600 OsiSolverInterface * solver =
00601 (s.nonlinearSolver() == s.continuousSolver())?
00602 model_.solver() : s.nonlinearSolver();
00603 bestSolution_ = new double[solver->getNumCols()];
00604 CoinCopyN(solver->getColSolution(), solver->getNumCols(),
00605 bestSolution_);
00606 bestObj_ = bestBound_ = solver->getObjValue();
00607 }
00608
00609 if (bonBabInfoPtr->bestSolution2().size() > 0) {
00610 assert((int) bonBabInfoPtr->bestSolution2().size() == s.nonlinearSolver()->getNumCols());
00611 if (bestSolution_)
00612 delete [] bestSolution_;
00613 bestSolution_ = new double[s.nonlinearSolver()->getNumCols()];
00614 std::copy(bonBabInfoPtr->bestSolution2().begin(), bonBabInfoPtr->bestSolution2().end(),
00615 bestSolution_);
00616 bestObj_ = (bonBabInfoPtr->bestObj2());
00617 (*s.nonlinearSolver()->messageHandler())<<"\nReal objective function: "
00618 <<bestObj_<<CoinMessageEol;
00619 }
00620 else if (model_.bestSolution()) {
00621 if (bestSolution_)
00622 delete [] bestSolution_;
00623 bestSolution_ = new double[s.nonlinearSolver()->getNumCols()];
00624 CoinCopyN(model_.bestSolution(), s.nonlinearSolver()->getNumCols(), bestSolution_);
00625 }
00626 if(remaining_time <= 0.){
00627 status = TMINLP::LIMIT_EXCEEDED;
00628 if (bestSolution_) {
00629 mipStatus_ = Feasible;
00630 }
00631 else {
00632 mipStatus_ = NoSolutionKnown;
00633 }
00634 }
00635 else if (model_.status() == 0) {
00636 if(model_.isContinuousUnbounded()){
00637 status = TMINLP::CONTINUOUS_UNBOUNDED;
00638 mipStatus_ = UnboundedOrInfeasible;
00639 }
00640 else
00641 if (bestSolution_) {
00642 status = TMINLP::SUCCESS;
00643 mipStatus_ = FeasibleOptimal;
00644 }
00645 else {
00646 status = TMINLP::INFEASIBLE;
00647 mipStatus_ = ProvenInfeasible;
00648 }
00649 }
00650 else if (model_.status() == 1 || model_.status() == 5) {
00651 #if (BONMIN_VERSION_MAJOR > 1) || (BONMIN_VERSION_MINOR > 6)
00652 status = model_.status() == 1 ? TMINLP::LIMIT_EXCEEDED : TMINLP::USER_INTERRUPT;
00653 #else
00654 status = TMINLP::LIMIT_EXCEEDED;
00655 #endif
00656 if (bestSolution_) {
00657 mipStatus_ = Feasible;
00658 }
00659 else {
00660 mipStatus_ = NoSolutionKnown;
00661 }
00662 }
00663 else if (model_.status()==2) {
00664 status = TMINLP::MINLP_ERROR;
00665 }
00666
00667
00668 bool use_RBS_Cbc =
00669 !problem_ ||
00670 !(problem_ -> getRecordBestSol ()) ||
00671 !(problem_ -> getRecordBestSol () -> getHasSol()) ||
00672 (((fabs (bestObj_) < COUENNE_INFINITY / 1e4) &&
00673 (problem_ -> getRecordBestSol () -> getVal () > bestObj_)));
00674
00675
00676 assert(use_RBS_Cbc || problem_ -> getRecordBestSol () -> getSol() != NULL);
00677
00678 s.nonlinearSolver () -> model () -> finalize_solution
00679 (status,
00680 s.nonlinearSolver () -> getNumCols (),
00681 use_RBS_Cbc ? bestSolution_ : problem_ -> getRecordBestSol () -> getSol (),
00682 use_RBS_Cbc ? bestObj_ : problem_ -> getRecordBestSol () -> getVal ());
00683 }
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696 const double * CouenneBab::bestSolution() const {
00697 if(!problem_ ||
00698 !(problem_ -> getRecordBestSol ()) ||
00699 !(problem_ -> getRecordBestSol () -> getHasSol()) ||
00700 (((fabs (bestObj_) < COUENNE_INFINITY / 1e4) &&
00701 (problem_ -> getRecordBestSol () -> getVal () > bestObj_))))
00702 return bestSolution_;
00703 return problem_ -> getRecordBestSol () -> getSol ();
00704 }
00705
00706 double CouenneBab::bestObj() const {
00707 if(!problem_ ||
00708 !(problem_ -> getRecordBestSol ()) ||
00709 !(problem_ -> getRecordBestSol () -> getHasSol()) ||
00710 (((fabs (bestObj_) < COUENNE_INFINITY / 1e4) &&
00711 (problem_ -> getRecordBestSol () -> getVal () > bestObj_))))
00712 return bestObj_;
00713 return problem_ -> getRecordBestSol () -> getVal ();
00714 }