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