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