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