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 usingCouenne_(false)
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 bool ChangedObject = false;
00183
00184 if (s.continuousSolver()->objects()==NULL) {
00185
00186 const OsiTMINLPInterface * nlpSolver = s.nonlinearSolver();
00187
00188 const int * priorities = nlpSolver->getPriorities();
00189 const double * upPsCosts = nlpSolver->getUpPsCosts();
00190 const double * downPsCosts = nlpSolver->getDownPsCosts();
00191 const int * directions = nlpSolver->getBranchingDirections();
00192 bool hasPseudo = (upPsCosts!=NULL);
00193 model_.findIntegers(true,hasPseudo);
00194 OsiObject ** simpleIntegerObjects = model_.objects();
00195 int numberObjects = model_.numberObjects();
00196 if (priorities != NULL || directions != NULL || hasPseudo) {
00197 ChangedObject = true;
00198 for (int i = 0 ; i < numberObjects ; i++) {
00199 CbcObject * object = dynamic_cast<CbcObject *>
00200 (simpleIntegerObjects[i]);
00201 int iCol = object->columnNumber();
00202 if (priorities)
00203 object->setPriority(priorities[iCol]);
00204 if (directions)
00205 object->setPreferredWay(directions[iCol]);
00206 if (upPsCosts) {
00207 CbcSimpleIntegerPseudoCost * pscObject =
00208 dynamic_cast<CbcSimpleIntegerPseudoCost*> (object);
00209 pscObject->setUpPseudoCost(upPsCosts[iCol]);
00210 pscObject->setDownPseudoCost(downPsCosts[iCol]);
00211 }
00212 }
00213 }
00214
00215 #if 1
00216
00217 const TMINLP::SosInfo * sos = s.nonlinearSolver()->model()->sosConstraints();
00218 if (!s.getIntParameter(BabSetupBase::DisableSos) && sos && sos->num > 0)
00219
00220 {
00221 const OsiTMINLPInterface * nlpSolver = s.nonlinearSolver();
00222 const int & numSos = sos->num;
00223 (*nlpSolver->messageHandler())<<"Adding "<<sos->num<<" sos constraints."
00224 <<CoinMessageEol;
00225
00226 CbcObject ** objects = new CbcObject*[numSos];
00227 const int * starts = sos->starts;
00228 const int * indices = sos->indices;
00229 const char * types = sos->types;
00230 const double * weights = sos->weights;
00231
00232 bool hasPriorities = false;
00233 const int * varPriorities = nlpSolver->getPriorities();
00234 int numberObjects = model_.numberObjects();
00235 if (varPriorities)
00236 {
00237 for (int i = 0 ; i < numberObjects ; i++) {
00238 if (varPriorities[i]) {
00239 hasPriorities = true;
00240 break;
00241 }
00242 }
00243 }
00244 const int * sosPriorities = sos->priorities;
00245 if (sosPriorities)
00246 {
00247 for (int i = 0 ; i < numSos ; i++) {
00248 if (sosPriorities[i]) {
00249 hasPriorities = true;
00250 break;
00251 }
00252 }
00253 }
00254 for (int i = 0 ; i < numSos ; i++)
00255 {
00256 int start = starts[i];
00257 int length = starts[i + 1] - start;
00258 #ifdef DO_IT_NWAY
00259 printf("setting nway object\n"),
00260 objects[i] = new CbcNWay(&model_, length, &indices[start],
00261 i);
00262 objects[i]->setPriority(1);
00263 #else
00264 objects[i] = new CbcSOS(&model_, length, &indices[start],
00265 &weights[start], i, types[i]);
00266 objects[i]->setPriority(10);
00267 #endif
00268 if (hasPriorities && sosPriorities && sosPriorities[i]) {
00269 objects[i]->setPriority(sosPriorities[i]);
00270 }
00271 }
00272 model_.addObjects(numSos, objects);
00273 for (int i = 0 ; i < numSos ; i++)
00274 delete objects[i];
00275 delete [] objects;
00276 }
00277 #endif
00278
00279 if (s.objects().size()) {
00280 CbcObject ** objects = new CbcObject *[s.objects().size()];
00281 for (unsigned int i = 0 ; i < s.objects().size() ; i++) {
00282 objects[i] = dynamic_cast<CbcObject *> (s.objects()[i]);
00283 assert(objects[i]);
00284 objects[i]->setModel(&model_);
00285 }
00286 model_.addObjects(s.objects().size(), objects);
00287 delete [] objects;
00288 }
00289
00290 replaceIntegers(model_.objects(), model_.numberObjects());
00291 }
00292 else {
00293
00294 assert (s.branchingMethod() != NULL);
00295
00296 if (!usingCouenne_)
00297 model_.addObjects (s.continuousSolver()->numberObjects(),
00298 s.continuousSolver()->objects());
00299 else {
00300
00301 int nco = s.continuousSolver () -> numberObjects ();
00302 OsiObject **objs = new OsiObject * [nco];
00303 for (int i=0; i<nco; i++)
00304 objs [i] = s.continuousSolver () -> objects () [i];
00305 model_.addObjects (nco, objs);
00306 delete [] objs;
00307 }
00308
00309 CbcBranchDefaultDecision branch;
00310 s.branchingMethod()->setSolver(model_.solver());
00311 BonChooseVariable * strong2 = dynamic_cast<BonChooseVariable *>(s.branchingMethod());
00312 if (strong2)
00313 strong2->setCbcModel(&model_);
00314 branch.setChooseMethod(*s.branchingMethod());
00315
00316 model_.setBranchingMethod(&branch);
00317
00318 model_.solver()->deleteObjects();
00319 }
00320
00321 model_.setDblParam(CbcModel::CbcCutoffIncrement, s.getDoubleParameter(BabSetupBase::CutoffDecr));
00322
00323 model_.setCutoff(s.getDoubleParameter(BabSetupBase::Cutoff) + CUTOFF_TOL);
00324
00325 model_.setDblParam(CbcModel::CbcAllowableGap, s.getDoubleParameter(BabSetupBase::AllowableGap));
00326 model_.setDblParam(CbcModel::CbcAllowableFractionGap, s.getDoubleParameter(BabSetupBase::AllowableFractionGap));
00327
00328
00329
00330 if (s.nodeComparisonMethod()==BabSetupBase::bestBound) {
00331 CbcCompareObjective compare;
00332 model_.setNodeComparison(compare);
00333 }
00334 else if (s.nodeComparisonMethod()==BabSetupBase::DFS) {
00335 CbcCompareDepth compare;
00336 model_.setNodeComparison(compare);
00337 }
00338 else if (s.nodeComparisonMethod()==BabSetupBase::BFS) {
00339 CbcCompareDefault compare;
00340 compare.setWeight(0.0);
00341 model_.setNodeComparison(compare);
00342 }
00343 else if (s.nodeComparisonMethod()==BabSetupBase::dynamic) {
00344 CbcCompareDefault compare;
00345 model_.setNodeComparison(compare);
00346 }
00347 else if (s.nodeComparisonMethod()==BabSetupBase::bestGuess) {
00348
00349
00350 CbcCompareEstimate compare;
00351 model_.setNodeComparison(compare);
00352 GuessHeuristic * guessHeu = new GuessHeuristic(model_);
00353 model_.addHeuristic(guessHeu);
00354 delete guessHeu;
00355 }
00356
00357 if (s.treeTraversalMethod() == BabSetupBase::HeapOnly) {
00358
00359 }
00360 else if (s.treeTraversalMethod() == BabSetupBase::DiveFromBest) {
00361 CbcDiver treeTraversal;
00362 treeTraversal.initialize(s);
00363 model_.passInTreeHandler(treeTraversal);
00364 }
00365 else if (s.treeTraversalMethod() == BabSetupBase::ProbedDive) {
00366 CbcProbedDiver treeTraversal;
00367 treeTraversal.initialize(s);
00368 model_.passInTreeHandler(treeTraversal);
00369 }
00370 else if (s.treeTraversalMethod() == BabSetupBase::DfsDiveFromBest) {
00371 CbcDfsDiver treeTraversal;
00372 treeTraversal.initialize(s);
00373 model_.passInTreeHandler(treeTraversal);
00374 }
00375 else if (s.treeTraversalMethod() == BabSetupBase::DfsDiveDynamic) {
00376 CbcDfsDiver treeTraversal;
00377 treeTraversal.initialize(s);
00378 model_.passInTreeHandler(treeTraversal);
00379
00380 DiverCompare compare;
00381 compare.setComparisonDive(*model_.nodeComparison());
00382 compare.setComparisonBound(CbcCompareObjective());
00383 CbcDfsDiver * dfs = dynamic_cast<CbcDfsDiver *> (model_.tree());
00384 assert(dfs);
00385 compare.setDiver(dfs);
00386 model_.setNodeComparison(compare);
00387 }
00388
00389 model_.setNumberStrong(s.getIntParameter(BabSetupBase::NumberStrong));
00390
00391 model_.setNumberBeforeTrust(s.getIntParameter(BabSetupBase::MinReliability));
00392 model_.setNumberPenalties(8);
00393
00394 model_.setDblParam(CbcModel::CbcMaximumSeconds, s.getDoubleParameter(BabSetupBase::MaxTime));
00395
00396 model_.setMaximumNodes(s.getIntParameter(BabSetupBase::MaxNodes));
00397
00398 model_.setMaximumNumberIterations(s.getIntParameter(BabSetupBase::MaxIterations));
00399
00400 model_.setMaximumSolutions(s.getIntParameter(BabSetupBase::MaxSolutions));
00401
00402 model_.setIntegerTolerance(s.getDoubleParameter(BabSetupBase::IntTol));
00403
00404
00405
00406
00407
00408 OsiObject ** objects = model_.objects();
00409 if (specOpt!=16 && objects) {
00410 int numberObjects = model_.numberObjects();
00411 if (objects_ != NULL) {
00412 for (int i = 0 ; i < nObjects_; i++)
00413 delete objects_[i];
00414 }
00415 delete [] objects_;
00416 objects_ = new OsiObject*[numberObjects];
00417 nObjects_ = numberObjects;
00418 for (int i = 0 ; i < numberObjects; i++) {
00419 OsiObject * obj = objects[i];
00420 CbcSimpleInteger * intObj = dynamic_cast<CbcSimpleInteger *> (obj);
00421 if (intObj) {
00422 objects_[i] = intObj->osiObject();
00423 }
00424 else {
00425 CbcSOS * sosObj = dynamic_cast<CbcSOS *>(obj);
00426 if (sosObj) objects_[i] = sosObj->osiObject(model_.solver());
00427 else {
00428 CbcObject * cbcObj = dynamic_cast<CbcObject *>(obj);
00429 if (cbcObj) {
00430 std::cerr<<"Unsupported CbcObject appears in the code"<<std::endl;
00431 throw UNSUPPORTED_CBC_OBJECT;
00432 }
00433 else {
00434 objects_[i]=obj->clone();
00435 }
00436 }
00437 }
00438 }
00439 CbcCutGenerator ** gen = model_.cutGenerators();
00440 int numGen = model_.numberCutGenerators();
00441 for (int i = 0 ; i < numGen ; i++) {
00442 OaDecompositionBase * oa = dynamic_cast<OaDecompositionBase * >(gen[i]->generator());
00443 if (oa)
00444 oa->setObjects(objects_,nObjects_);
00445 }
00446 }
00447
00448
00449 try {
00450
00451 {
00452 OsiTMINLPInterface * tmpOsi = NULL;
00453 if(s.nonlinearSolver() == s.continuousSolver()){
00454 tmpOsi = dynamic_cast<OsiTMINLPInterface *> (model_.solver());
00455 tmpOsi->forceSolverOutput(s.getIntParameter(BabSetupBase::RootLogLevel));
00456 }
00457 model_.initialSolve();
00458 if(tmpOsi != NULL){
00459 tmpOsi->setSolverOutputToDefault();
00460 }
00461 }
00462
00463 int ival;
00464 s.options()->GetEnumValue("enable_dynamic_nlp", ival, "bonmin.");
00465 if(s.nonlinearSolver() == s.continuousSolver() && ival)
00466 {
00467 if(!model_.solver()->isProvenOptimal() ){
00468
00469 OsiTMINLPInterface * tmpOsi = dynamic_cast<OsiTMINLPInterface *> (model_.solver());
00470 TMINLPLinObj * tmp_tminlp = dynamic_cast<TMINLPLinObj *> (tmpOsi->model());
00471 tmpOsi->setModel(tmp_tminlp->tminlp());
00472 model_.initialSolve();
00473 }
00474 else {
00475 LinearCutsGenerator cgl;
00476 cgl.initialize(s);
00477 OsiCuts cuts;
00478 cgl.generateCuts(*model_.solver(), cuts);
00479 std::vector<OsiRowCut *> mycuts(cuts.sizeRowCuts());
00480 for(int i = 0 ; i < cuts.sizeRowCuts() ; i++){
00481 mycuts[i] = cuts.rowCutPtr(i);
00482 }
00483 model_.solver()->applyRowCuts(mycuts.size(), (const OsiRowCut **) &mycuts[0]);
00484 }
00485
00486
00487 OsiTMINLPInterface * nlpSolver = dynamic_cast<OsiTMINLPInterface *>(model_.solver());
00488 if(nlpSolver && nlpSolver->getNewCutoffDecr()!=COIN_DBL_MAX)
00489 model_.setDblParam(CbcModel::CbcCutoffIncrement, nlpSolver->getNewCutoffDecr());
00490
00491 model_.solver()->resolve();
00492
00493 }
00494
00495
00496 if (usingCouenne_)
00497 model_.passInSolverCharacteristics (bonBabInfoPtr);
00498
00499 continuousRelaxation_ =model_.solver()->getObjValue();
00500 if (specOpt==16)
00501 {
00502 #if 1
00503 const double * colsol = model_.solver()->getColSolution();
00504 const double * duals = model_.solver()->getRowPrice();
00505
00506 OsiTMINLPInterface * tnlpSolver = dynamic_cast<OsiTMINLPInterface *>(model_.solver());
00507
00508 if(tnlpSolver->problem()->has_x_init() != 2){
00509 model_.solver()->setColSolution(colsol);
00510 model_.solver()->setRowPrice(duals);
00511 }
00512 #else
00513 OsiTMINLPInterface * tnlpSolver = dynamic_cast<OsiTMINLPInterface *>(model_.solver());
00514 CoinWarmStart * warm = tnlpSolver->solver()->getWarmStart(tnlpSolver->problem());
00515 tnlpSolver->solver()->setWarmStart(warm, tnlpSolver->problem());
00516 delete warm;
00517 #endif
00518
00519 #if 0 // Sometimes primal dual point is problematic in the context of Cut-and-branch
00520 model_.solver()->resolve();
00521 if(!model_.solver()->isProvenOptimal())
00522 model_.solver()->setColSolution(NULL);
00523 #endif
00524 }
00525
00526 #ifdef SIGNAL
00527 CoinSighandler_t saveSignal=SIG_DFL;
00528
00529 saveSignal = signal(SIGINT,signal_handler);
00530 #endif
00531
00532 currentBranchModel = &model_;
00533
00534
00535
00536 remaining_time -= CoinCpuTime();
00537 model_.setDblParam(CbcModel::CbcMaximumSeconds, remaining_time);
00538 if(remaining_time > 0.)
00539 model_.branchAndBound();
00540 }
00541 catch(TNLPSolver::UnsolvedError *E){
00542 s.nonlinearSolver()->model()->finalize_solution(TMINLP::MINLP_ERROR,
00543 0,
00544 NULL,
00545 DBL_MAX);
00546 throw E;
00547
00548 }
00549 numNodes_ = model_.getNodeCount();
00550 bestObj_ = model_.getObjValue();
00551 bestBound_ = model_.getBestPossibleObjValue();
00552 mipIterationCount_ = model_.getIterationCount();
00553
00554 bool hasFailed = false;
00555 if (specOpt==16)
00556 {
00557 CbcNlpStrategy * nlpStrategy = dynamic_cast<CbcNlpStrategy *>(model_.strategy());
00558 if (nlpStrategy)
00559 hasFailed = nlpStrategy->hasFailed();
00560 else
00561 throw -1;
00562 }
00563 else
00564 hasFailed = s.nonlinearSolver()->hasContinuedOnAFailure();
00565
00566
00567
00568
00569
00570
00571 int numberGenerators = model_.numberCutGenerators();
00572 for (int iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
00573 CbcCutGenerator * generator = model_.cutGenerator(iGenerator);
00574
00575 if (true&&!(generator->numberCutsInTotal() || generator->numberColumnCuts()))
00576 continue;
00577 if(modelHandler_->logLevel() >= 1) {
00578 *modelHandler_ << generator->cutGeneratorName()
00579 << "was tried" << generator->numberTimesEntered()
00580 << "times and created" << generator->numberCutsInTotal()+generator->numberColumnCuts()
00581 << "cuts of which" << generator->numberCutsActive()
00582 << "were active after adding rounds of cuts";
00583 if (generator->timing()) {
00584 char timebuf[20];
00585 sprintf(timebuf, "(%.3fs)", generator->timeInCutGenerator());
00586 *modelHandler_ << timebuf << CoinMessageEol;
00587 }
00588 else {
00589 *modelHandler_ << CoinMessageEol;
00590 }
00591 }
00592 }
00593
00594 if (hasFailed && !usingCouenne_) {
00595 *model_.messageHandler()
00596 << "************************************************************" << CoinMessageEol
00597 << "WARNING : Optimization failed on an NLP during optimization" << CoinMessageEol
00598 << " (no optimal value found within tolerances)." << CoinMessageEol
00599 << " Optimization was not stopped because option" << CoinMessageEol
00600 << "\"nlp_failure_behavior\" has been set to fathom but" << CoinMessageEol
00601 << " beware that reported solution may not be optimal" << CoinMessageEol
00602 << "************************************************************" << CoinMessageEol;
00603 }
00604 TMINLP::SolverReturn status = TMINLP::MINLP_ERROR;
00605
00606 if (model_.numberObjects()==0) {
00607 if (bestSolution_)
00608 delete [] bestSolution_;
00609 OsiSolverInterface * solver =
00610 (s.nonlinearSolver() == s.continuousSolver())?
00611 model_.solver() : s.nonlinearSolver();
00612 bestSolution_ = new double[solver->getNumCols()];
00613 CoinCopyN(solver->getColSolution(), solver->getNumCols(),
00614 bestSolution_);
00615 bestObj_ = bestBound_ = solver->getObjValue();
00616 }
00617
00618 if (bonBabInfoPtr->bestSolution2().size() > 0) {
00619 assert((int) bonBabInfoPtr->bestSolution2().size() == s.nonlinearSolver()->getNumCols());
00620 if (bestSolution_)
00621 delete [] bestSolution_;
00622 bestSolution_ = new double[s.nonlinearSolver()->getNumCols()];
00623 std::copy(bonBabInfoPtr->bestSolution2().begin(), bonBabInfoPtr->bestSolution2().end(),
00624 bestSolution_);
00625 bestObj_ = (bonBabInfoPtr->bestObj2());
00626 (*s.nonlinearSolver()->messageHandler())<<"\nReal objective function: "
00627 <<bestObj_<<CoinMessageEol;
00628 }
00629 else if (model_.bestSolution()) {
00630 if (bestSolution_)
00631 delete [] bestSolution_;
00632 bestSolution_ = new double[s.nonlinearSolver()->getNumCols()];
00633 CoinCopyN(model_.bestSolution(), s.nonlinearSolver()->getNumCols(), bestSolution_);
00634 }
00635 if(remaining_time <= 0.){
00636 status = TMINLP::LIMIT_EXCEEDED;
00637 if (bestSolution_) {
00638 mipStatus_ = Feasible;
00639 }
00640 }
00641 else if (model_.status() == 0) {
00642 if(model_.isContinuousUnbounded()){
00643 status = TMINLP::CONTINUOUS_UNBOUNDED;
00644 mipStatus_ = UnboundedOrInfeasible;
00645 }
00646 else
00647 if (bestSolution_) {
00648 status = TMINLP::SUCCESS;
00649 mipStatus_ = FeasibleOptimal;
00650 }
00651 else {
00652 status = TMINLP::INFEASIBLE;
00653 mipStatus_ = ProvenInfeasible;
00654 }
00655 }
00656 else if (model_.status() == 1) {
00657 status = TMINLP::LIMIT_EXCEEDED;
00658 if (bestSolution_) {
00659 mipStatus_ = Feasible;
00660 }
00661 else {
00662 mipStatus_ = NoSolutionKnown;
00663 }
00664 }
00665 else if (model_.status()==2) {
00666 status = TMINLP::MINLP_ERROR;
00667 }
00668 s.nonlinearSolver()->model()->finalize_solution(status,
00669 s.nonlinearSolver()->getNumCols(),
00670 bestSolution_,
00671 bestObj_);
00672 }
00673
00674
00676 double
00677 Bab::bestBound()
00678 {
00679 if (mipStatus_ == FeasibleOptimal) return bestObj_;
00680 else if (mipStatus_ == ProvenInfeasible) return 1e200;
00681 else return bestBound_;
00682 }
00683
00684
00685 }