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