BonCbc.cpp
Go to the documentation of this file.
1 // (C) Copyright International Business Machines Corporation 2007
2 // All Rights Reserved.
3 // This code is published under the Eclipse Public License.
4 //
5 // Authors :
6 // Pierre Bonami, International Business Machines Corporation
7 //
8 // Date : 04/19/2007
9 
10 
11 #include "BonCbc.hpp"
12 #include "BonOACutGenerator2.hpp"
13 #include "BonCbcNlpStrategy.hpp"
14 #include "BonBabInfos.hpp"
15 #include "CbcModel.hpp"
16 #include "CbcBranchActual.hpp"
17 #include "CbcCutGenerator.hpp"
18 #include "CbcCompareActual.hpp"
19 #include "CbcCompareObjective.hpp"
20 #include "CbcCompareEstimate.hpp"
21 
22 #include "BonExitCodes.hpp"
23 
24 #include "BonChooseVariable.hpp"
25 #include "BonGuessHeuristic.hpp"
26 
27 #include "BonDiver.hpp"
29 #include "BonTMINLPLinObj.hpp"
30 // sets cutoff a bit above real one, to avoid single-point feasible sets
31 #define CUTOFF_TOL 1e-6
32 
33 // Code to enable user interuption
34 static CbcModel * currentBranchModel = NULL; //pointer to the main b&b
35 Bonmin::OACutGenerator2 * currentOA = NULL; //pointer to the OA generator
36 CbcModel * OAModel; // pointer to the submip if using Cbc
38 
39 #define SIGNAL
40 #ifdef SIGNAL
41 #include "CoinSignal.hpp"
42 
43 extern "C"
44 {
45 
46  static bool BonminInteruptedOnce =false;
47  static void signal_handler(int whichSignal) {
48  if (BonminInteruptedOnce) {
49  std::cerr<<"User forced interuption"<<std::endl;
50  exit(0);
51  }
52  if (currentBranchModel!=NULL)
53  currentBranchModel->sayEventHappened(); // stop at next node
54  if (OAModel!=NULL)
55  OAModel->sayEventHappened(); // stop at next node
56  if (currentOA!=NULL)
57  currentOA->parameter().maxLocalSearchTime_ = 0.; // stop OA
58 
59  BonminAbortAll = true;
60  BonminInteruptedOnce = true;
61  return;
62  }
63 }
64 #endif
65 
66 namespace Bonmin
67 {
68 
71  bestSolution_(NULL),
72  mipStatus_(),
73  bestObj_(1e200),
74  bestBound_(-1e200),
75  continuousRelaxation_(-COIN_DBL_MAX),
76  numNodes_(0),
77  mipIterationCount_(0),
78  model_(),
79  modelHandler_(NULL),
80  objects_(0),
81  nObjects_(0)
82  {}
83 
86  {
87  if (bestSolution_) delete [] bestSolution_;
88  bestSolution_ = NULL;
89  for ( int i = 0 ; i < nObjects_ ; i++) {
90  delete objects_[i];
91  }
92  delete [] objects_;
93  delete modelHandler_;
94  }
95 
97  void
99  {
100  branchAndBound(s);
101  }
102 
104  void
106  {
107 
108  double remaining_time = s.getDoubleParameter(BabSetupBase::MaxTime) + CoinCpuTime();
109  /* Put a link to this into solver.*/
110  OsiBabSolver * babInfo = dynamic_cast<OsiBabSolver *>(s.continuousSolver()->getAuxiliaryInfo());
111  assert(babInfo);
112  Bonmin::BabInfo * bonBabInfoPtr = dynamic_cast<Bonmin::BabInfo*>(babInfo);
113  if (bonBabInfoPtr == NULL) {//Replace with a Bonmin::babInfo
114  bonBabInfoPtr = new Bonmin::BabInfo(*babInfo);
115  s.continuousSolver()->setAuxiliaryInfo(bonBabInfoPtr);
116  delete bonBabInfoPtr;
117  bonBabInfoPtr = dynamic_cast<Bonmin::BabInfo*>(s.continuousSolver()->getAuxiliaryInfo());
118  }
119  bonBabInfoPtr->setBabPtr(this);
120 
122  OsiSolverInterface * solver = s.continuousSolver()->clone();
123  delete modelHandler_;
124  modelHandler_ = s.continuousSolver()->messageHandler()->clone();
125  model_.passInMessageHandler(modelHandler_);
126  model_.assignSolver(solver, true);
127 
128 
129  // s.continuousSolver() = model_.solver();
130  // if(s.continuousSolver()->objects()!=NULL){
131  // model_.addObjects(s.continuousSolver()->numberObjects(),s.continuousSolver()->objects());
132  // }
133 
135  if (specOpt) {
136  model_.setSpecialOptions(specOpt);
137  if (specOpt==16) {
141  model_.setStrategy(strat);
142  }
143  }
144 
145  model_.setMaximumCutPasses(s.getIntParameter(BabSetupBase::NumCutPasses));
146  model_.setMaximumCutPassesAtRoot(s.getIntParameter(BabSetupBase::NumCutPassesAtRoot));
147 
148  //Setup cutting plane methods
149  for (BabSetupBase::CuttingMethods::iterator i = s.cutGenerators().begin() ;
150  i != s.cutGenerators().end() ; i++) {
151 
152  OaDecompositionBase * oa = dynamic_cast<OaDecompositionBase *>(i->cgl);
153  if (oa && oa->reassignLpsolver())
154  oa->assignLpInterface(model_.solver());
155  model_.addCutGenerator(i->cgl,i->frequency,i->id.c_str(), i->normal,
156  i->atSolution);
157  if(i->always){
158  model_.cutGenerators()[model_.numberCutGenerators()-1]
159  ->setMustCallAgain(true);
160  }
161  }
162 
163  for (BabSetupBase::HeuristicMethods::iterator i = s.heuristics().begin() ;
164  i != s.heuristics().end() ; i++) {
165  CbcHeuristic * heu = i->heuristic;
166  heu->setModel(&model_);
167  model_.addHeuristic(heu, i->id.c_str());
168  }
169 
170 
171  //need to record solver logLevel here
172  int logLevel = s.continuousSolver()->messageHandler()->logLevel();
173 
174  //Set true branch-and-bound parameters
176 
177  // Put back solver logLevel
178  model_.solver()->messageHandler()->setLogLevel(logLevel);
179 
181 
182  //Pass over user set branching priorities to Cbc
183  if (s.continuousSolver()->objects()==NULL) {
184  //assert (s.branchingMethod() == NULL);
185  const OsiTMINLPInterface * nlpSolver = s.nonlinearSolver();
186  //set priorities, prefered directions...
187  const int * priorities = nlpSolver->getPriorities();
188  const double * upPsCosts = nlpSolver->getUpPsCosts();
189  const double * downPsCosts = nlpSolver->getDownPsCosts();
190  const int * directions = nlpSolver->getBranchingDirections();
191  bool hasPseudo = (upPsCosts!=NULL);
192  model_.findIntegers(true,hasPseudo);
193  OsiObject ** simpleIntegerObjects = model_.objects();
194  int numberObjects = model_.numberObjects();
195  if (priorities != NULL || directions != NULL || hasPseudo) {
196  for (int i = 0 ; i < numberObjects ; i++) {
197  CbcObject * object = dynamic_cast<CbcObject *>
198  (simpleIntegerObjects[i]);
199  int iCol = object->columnNumber();
200  if (priorities)
201  object->setPriority(priorities[iCol]);
202  if (directions)
203  object->setPreferredWay(directions[iCol]);
204  if (upPsCosts) {
205  CbcSimpleIntegerPseudoCost * pscObject =
206  dynamic_cast<CbcSimpleIntegerPseudoCost*> (object);
207  pscObject->setUpPseudoCost(upPsCosts[iCol]);
208  pscObject->setDownPseudoCost(downPsCosts[iCol]);
209  }
210  }
211  }
212 
213 #if 1
214  // Now pass user set Sos constraints (code inspired from CoinSolve.cpp)
215  const TMINLP::SosInfo * sos = s.nonlinearSolver()->model()->sosConstraints();
216  if (!s.getIntParameter(BabSetupBase::DisableSos) && sos && sos->num > 0)
217  //we have some sos constraints
218  {
219  const OsiTMINLPInterface * nlpSolver = s.nonlinearSolver();
220  const int & numSos = sos->num;
221  (*nlpSolver->messageHandler())<<"Adding "<<sos->num<<" sos constraints."
222  <<CoinMessageEol;
223 
224  CbcObject ** objects = new CbcObject*[numSos];
225  const int * starts = sos->starts;
226  const int * indices = sos->indices;
227  const char * types = sos->types;
228  const double * weights = sos->weights;
229  //verify if model has user set priorities
230  bool hasPriorities = false;
231  const int * varPriorities = nlpSolver->getPriorities();
232  int numberObjects = model_.numberObjects();
233  if (varPriorities)
234  {
235  for (int i = 0 ; i < numberObjects ; i++) {
236  if (varPriorities[i]) {
237  hasPriorities = true;
238  break;
239  }
240  }
241  }
242  const int * sosPriorities = sos->priorities;
243  if (sosPriorities)
244  {
245  for (int i = 0 ; i < numSos ; i++) {
246  if (sosPriorities[i]) {
247  hasPriorities = true;
248  break;
249  }
250  }
251  }
252  for (int i = 0 ; i < numSos ; i++)
253  {
254  int start = starts[i];
255  int length = starts[i + 1] - start;
256 #ifdef DO_IT_NWAY
257  printf("setting nway object\n"),
258  objects[i] = new CbcNWay(&model_, length, &indices[start],
259  i);
260  objects[i]->setPriority(1);
261 #else
262  objects[i] = new CbcSOS(&model_, length, &indices[start],
263  &weights[start], i, types[i]);
264  objects[i]->setPriority(10);
265 #endif
266  if (hasPriorities && sosPriorities && sosPriorities[i]) {
267  objects[i]->setPriority(sosPriorities[i]);
268  }
269  }
270  model_.addObjects(numSos, objects);
271  for (int i = 0 ; i < numSos ; i++)
272  delete objects[i];
273  delete [] objects;
274  }
275 #endif
276  //If Setup contains more objects add them to Cbc
277  if (s.objects().size()) {
278  CbcObject ** objects = new CbcObject *[s.objects().size()];
279  for (unsigned int i = 0 ; i < s.objects().size() ; i++) {
280  objects[i] = dynamic_cast<CbcObject *> (s.objects()[i]);
281  assert(objects[i]);
282  objects[i]->setModel(&model_);
283  }
284  model_.addObjects((int)s.objects().size(), objects);
285  delete [] objects;
286  }
287 
288  replaceIntegers(model_.objects(), model_.numberObjects());
289  }
290  else {//Pass in objects to Cbc
291  // Redundant definition of default branching (as Default == User)
292  assert (s.branchingMethod() != NULL);
293 
294  model_.addObjects (s.continuousSolver()->numberObjects(),
295  s.continuousSolver()->objects());
296 
297  CbcBranchDefaultDecision branch;
298  s.branchingMethod()->setSolver(model_.solver());
299  BonChooseVariable * strong2 = dynamic_cast<BonChooseVariable *>(s.branchingMethod());
300  if (strong2)
301  strong2->setCbcModel(&model_);
302  branch.setChooseMethod(*s.branchingMethod());
303 
304  model_.setBranchingMethod(&branch);
305  // prevent duplicating object when copying in CbcModel.cpp
306  model_.solver()->deleteObjects();
307  }
308 
309  model_.setDblParam(CbcModel::CbcCutoffIncrement, s.getDoubleParameter(BabSetupBase::CutoffDecr));
310 
312 
313  model_.setDblParam(CbcModel::CbcAllowableGap, s.getDoubleParameter(BabSetupBase::AllowableGap));
314  model_.setDblParam(CbcModel::CbcAllowableFractionGap, s.getDoubleParameter(BabSetupBase::AllowableFractionGap));
315 
316  // Definition of node selection strategy
317 
319  CbcCompareObjective compare;
320  model_.setNodeComparison(compare);
321  }
322  else if (s.nodeComparisonMethod()==BabSetupBase::DFS) {
323  CbcCompareDepth compare;
324  model_.setNodeComparison(compare);
325  }
326  else if (s.nodeComparisonMethod()==BabSetupBase::BFS) {
327  CbcCompareDefault compare;
328  compare.setWeight(0.0);
329  model_.setNodeComparison(compare);
330  }
332  CbcCompareDefault compare;
333  model_.setNodeComparison(compare);
334  }
336  // Right now, this is a mess. We need a separation of the
337  // pseudo costs from the ChooseVariable method
338  CbcCompareEstimate compare;
339  model_.setNodeComparison(compare);
340  GuessHeuristic * guessHeu = new GuessHeuristic(model_);
341  model_.addHeuristic(guessHeu);
342  delete guessHeu;
343  }
344 
346  //Do nothing this is the default of Cbc.
347  }
349  CbcDiver treeTraversal;
350  treeTraversal.initialize(s);
351  model_.passInTreeHandler(treeTraversal);
352  }
354  CbcProbedDiver treeTraversal;
355  treeTraversal.initialize(s);
356  model_.passInTreeHandler(treeTraversal);
357  }
359  CbcDfsDiver treeTraversal;
360  treeTraversal.initialize(s);
361  model_.passInTreeHandler(treeTraversal);
362  }
364  CbcDfsDiver treeTraversal;
365  treeTraversal.initialize(s);
366  model_.passInTreeHandler(treeTraversal);
367 
368  DiverCompare compare;
369  compare.setComparisonDive(*model_.nodeComparison());
370  compare.setComparisonBound(CbcCompareObjective());
371  CbcDfsDiver * dfs = dynamic_cast<CbcDfsDiver *> (model_.tree());
372  assert(dfs);
373  compare.setDiver(dfs);
374  model_.setNodeComparison(compare);
375  }
376 
378  model_.setNumberBeforeTrust(s.getIntParameter(BabSetupBase::MinReliability));
379  model_.setNumberPenalties(8);
380 
381  model_.setDblParam(CbcModel::CbcMaximumSeconds, s.getDoubleParameter(BabSetupBase::MaxTime));
382 
383  model_.setMaximumNodes(s.getIntParameter(BabSetupBase::MaxNodes));
384 
385  model_.setMaximumNumberIterations(s.getIntParameter(BabSetupBase::MaxIterations));
386 
387  model_.setMaximumSolutions(s.getIntParameter(BabSetupBase::MaxSolutions));
388 
389  model_.setIntegerTolerance(s.getDoubleParameter(BabSetupBase::IntTol));
390 
391 
392 
393  //Get objects from model_ if it is not null means there are some sos constraints or non-integer branching object
394  // pass them to cut generators.
395  OsiObject ** objects = model_.objects();
396  if (specOpt!=16 && objects) {
397  int numberObjects = model_.numberObjects();
398  if (objects_ != NULL) {
399  for (int i = 0 ; i < nObjects_; i++)
400  delete objects_[i];
401  }
402  delete [] objects_;
403  objects_ = new OsiObject*[numberObjects];
404  nObjects_ = numberObjects;
405  for (int i = 0 ; i < numberObjects; i++) {
406  OsiObject * obj = objects[i];
407  CbcSimpleInteger * intObj = dynamic_cast<CbcSimpleInteger *> (obj);
408  if (intObj) {
409  objects_[i] = intObj->osiObject();
410  }
411  else {
412  CbcSOS * sosObj = dynamic_cast<CbcSOS *>(obj);
413  if (sosObj) objects_[i] = sosObj->osiObject(model_.solver());
414  else {//Maybe an unsupported CbcObject
415  CbcObject * cbcObj = dynamic_cast<CbcObject *>(obj);
416  if (cbcObj) {
417  std::cerr<<"Unsupported CbcObject appears in the code"<<std::endl;
419  }
420  else {//It has to be an OsiObject.
421  objects_[i]=obj->clone();
422  }
423  }
424  }
425  }
426  CbcCutGenerator ** gen = model_.cutGenerators();
427  int numGen = model_.numberCutGenerators();
428  for (int i = 0 ; i < numGen ; i++) {
429  OaDecompositionBase * oa = dynamic_cast<OaDecompositionBase * >(gen[i]->generator());
430  if (oa)//pass objects
432  }
433  }
434 
435 #ifdef SIGNAL
436  //CoinSighandler_t saveSignal=SIG_DFL;
437  // register signal handler FIXME restore original signal handler when finished
438  /*saveSignal =*/ signal(SIGINT,signal_handler);
439 #endif
440 
442 
443 
444  try {
445  //Get the time and start.
446  {
447  OsiTMINLPInterface * tmpOsi = NULL;
448  if(s.nonlinearSolver() == s.continuousSolver()){
449  tmpOsi = dynamic_cast<OsiTMINLPInterface *> (model_.solver());
451  }
452  model_.initialSolve();
453  if(tmpOsi != NULL){
454  tmpOsi->setSolverOutputToDefault();
455  }
456  }
457 
459  int ival;
460  s.options()->GetEnumValue("enable_dynamic_nlp", ival, "bonmin.");
461  if(s.nonlinearSolver() == s.continuousSolver() && ival)
462  {
463  if(!model_.solver()->isProvenOptimal() ){//Something went wrong check if objective is linear and alternate model
464  // can be solved
465  OsiTMINLPInterface * tmpOsi = dynamic_cast<OsiTMINLPInterface *> (model_.solver());
466  TMINLPLinObj * tmp_tminlp = dynamic_cast<TMINLPLinObj *> (tmpOsi->model());
467  tmpOsi->setModel(tmp_tminlp->tminlp());
468  model_.initialSolve();
469  }
470  else {
472  cgl.initialize(s);
473  OsiCuts cuts;
474  cgl.generateCuts(*model_.solver(), cuts);
475  std::vector<OsiRowCut *> mycuts(cuts.sizeRowCuts());
476  for(int i = 0 ; i < cuts.sizeRowCuts() ; i++){
477  mycuts[i] = cuts.rowCutPtr(i);
478  }
479  model_.solver()->applyRowCuts((int)mycuts.size(), const_cast<const OsiRowCut **>(&mycuts[0]));
480  }
481 
482  //Added by Claudia
483  OsiTMINLPInterface * nlpSolver = dynamic_cast<OsiTMINLPInterface *>(model_.solver());
484  if(nlpSolver && nlpSolver->getNewCutoffDecr()!=COIN_DBL_MAX)
485  model_.setDblParam(CbcModel::CbcCutoffIncrement, nlpSolver->getNewCutoffDecr());
486 
487  model_.solver()->resolve();
488 
489  }
490 
491  continuousRelaxation_ =model_.solver()->getObjValue();
492  if (specOpt==16)//Set warm start point for Ipopt
493  {
494 #if 1
495  const double * colsol = model_.solver()->getColSolution();
496  const double * duals = model_.solver()->getRowPrice();
497 
498  OsiTMINLPInterface * tnlpSolver = dynamic_cast<OsiTMINLPInterface *>(model_.solver());
499  // Primal dual point is not copied if one (supposedely a better one) has already been put into the solver.
500  if(tnlpSolver->problem()->has_x_init() != 2){
501  if( colsol != NULL )
502  model_.solver()->setColSolution(colsol);
503  if( duals != NULL )
504  model_.solver()->setRowPrice(duals);
505  }
506 #else
507  OsiTMINLPInterface * tnlpSolver = dynamic_cast<OsiTMINLPInterface *>(model_.solver());
508  CoinWarmStart * warm = tnlpSolver->solver()->getWarmStart(tnlpSolver->problem());
509  tnlpSolver->solver()->setWarmStart(warm, tnlpSolver->problem());
510  delete warm;
511 #endif
512 
513 #if 0 // Sometimes primal dual point is problematic in the context of Cut-and-branch
514  model_.solver()->resolve();
515  if(!model_.solver()->isProvenOptimal())
516  model_.solver()->setColSolution(NULL);
517 #endif
518  }
519 
520  // to get node parent info in Cbc, pass parameter 3.
521  //model_.branchAndBound(3);
522  remaining_time -= CoinCpuTime();
523  model_.setDblParam(CbcModel::CbcMaximumSeconds, remaining_time);
524  if(remaining_time > 0.)
525  model_.branchAndBound();
526  }
527  }
528  catch(TNLPSolver::UnsolvedError *E){
530  0,
531  NULL,
532  DBL_MAX);
533  throw E;
534 
535  }
536  numNodes_ = model_.getNodeCount();
537  bestObj_ = model_.getObjValue();
538  bestBound_ = model_.getBestPossibleObjValue();
539  mipIterationCount_ = model_.getIterationCount();
540 
541  bool hasFailed = false;
542  if (specOpt==16)//Did we continue branching on a failure
543  {
544  CbcNlpStrategy * nlpStrategy = dynamic_cast<CbcNlpStrategy *>(model_.strategy());
545  if (nlpStrategy)
546  hasFailed = nlpStrategy->hasFailed();
547  else {
548  throw CoinError("BonCbc", "Bab", "Inconsistent construction of model_ strategy is"
549  " not the right type.");
550  }
551  }
552  else
553  hasFailed = s.nonlinearSolver()->hasContinuedOnAFailure();
554 
555  // Output summarizing cut generators (taken from CbcSolver.cpp)
556  // ToDo put into proper print level
557 
558 
559 
560  int numberGenerators = model_.numberCutGenerators();
561  for (int iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
562  CbcCutGenerator * generator = model_.cutGenerator(iGenerator);
563  //CglStored * stored = dynamic_cast<CglStored*>(generator->generator());
564  if (true&&!(generator->numberCutsInTotal() || generator->numberColumnCuts()))
565  continue;
566  if(modelHandler_->logLevel() >= 1) {
567  *modelHandler_ << generator->cutGeneratorName()
568  << "was tried" << generator->numberTimesEntered()
569  << "times and created" << generator->numberCutsInTotal()+generator->numberColumnCuts()
570  << "cuts of which" << generator->numberCutsActive()
571  << "were active after adding rounds of cuts";
572  if (generator->timing()) {
573  char timebuf[20];
574  sprintf(timebuf, "(%.3fs)", generator->timeInCutGenerator());
575  *modelHandler_ << timebuf << CoinMessageEol;
576  }
577  else {
578  *modelHandler_ << CoinMessageEol;
579  }
580  }
581  }
582 
583  if (hasFailed) {
584  *model_.messageHandler()
585  << "************************************************************" << CoinMessageEol
586  << "WARNING : Optimization failed on an NLP during optimization" << CoinMessageEol
587  << " (no optimal value found within tolerances)." << CoinMessageEol
588  << " Optimization was not stopped because option" << CoinMessageEol
589  << "\"nlp_failure_behavior\" has been set to fathom but" << CoinMessageEol
590  << " beware that reported solution may not be optimal" << CoinMessageEol
591  << "************************************************************" << CoinMessageEol;
592  }
594 
596  if (model_.numberObjects()==0) {
597  if (bestSolution_)
598  delete [] bestSolution_;
599  OsiSolverInterface * solver =
600  (s.nonlinearSolver() == s.continuousSolver())?
601  model_.solver() : s.nonlinearSolver();
602  if(! solver->isProvenOptimal()){
603  bestSolution_ = NULL;
604  if ( solver->isProvenPrimalInfeasible () ) {
605  status = TMINLP::INFEASIBLE;
607  bestObj_ = DBL_MAX;
608  bestBound_ = DBL_MAX;
609  }
610  else if ( solver->isProvenDualInfeasible () ) {
613  bestObj_ = - DBL_MAX;
614  bestBound_ = - DBL_MAX;
615  }
616  else {
618  bestObj_ = DBL_MAX;
619  bestBound_ = - DBL_MAX;
620  }
621  }
622  else {
623  bestSolution_ = new double[solver->getNumCols()];
624  CoinCopyN(solver->getColSolution(), solver->getNumCols(),
625  bestSolution_);
626  bestObj_ = bestBound_ = solver->getObjValue();
627  status = TMINLP::SUCCESS;
629  }
630  }
631  else {
632  if (bonBabInfoPtr->bestSolution2().size() > 0) {
633  assert((int) bonBabInfoPtr->bestSolution2().size() == s.nonlinearSolver()->getNumCols());
634  if (bestSolution_)
635  delete [] bestSolution_;
636  bestSolution_ = new double[s.nonlinearSolver()->getNumCols()];
637  std::copy(bonBabInfoPtr->bestSolution2().begin(), bonBabInfoPtr->bestSolution2().end(),
638  bestSolution_);
639  bestObj_ = (bonBabInfoPtr->bestObj2());
640  (*s.nonlinearSolver()->messageHandler())<<"\nReal objective function: "
641  <<bestObj_<<CoinMessageEol;
642  }
643  else if (model_.bestSolution()) {
644  if (bestSolution_)
645  delete [] bestSolution_;
646  bestSolution_ = new double[s.nonlinearSolver()->getNumCols()];
647  CoinCopyN(model_.bestSolution(), s.nonlinearSolver()->getNumCols(), bestSolution_);
648  }
649  if(remaining_time <= 0.){
650  status = TMINLP::LIMIT_EXCEEDED;
651  if (bestSolution_) {
653  }
654  else {
656  }
657  }
658  else if (model_.status() == 0) {
659  if(model_.isContinuousUnbounded()){
662  }
663  else
664  if (bestSolution_) {
665  status = TMINLP::SUCCESS;
667  }
668  else {
669  status = TMINLP::INFEASIBLE;
671  }
672  }
673  else if (model_.status() == 1 || model_.status() == 5) {
674  status = model_.status() == 1 ? TMINLP::LIMIT_EXCEEDED : TMINLP::USER_INTERRUPT;
675  if (bestSolution_) {
677  }
678  else {
680  }
681  }
682  else if (model_.status()==2) {
683  status = TMINLP::MINLP_ERROR;
684  }
685  }
686  s.nonlinearSolver()->model()->finalize_solution(status,
689  bestObj_);
690 }
691 
692 
694  double
696  {
697  if (mipStatus_ == ProvenInfeasible) return 1e200;
698  else return bestBound_;
699  }
700 
701 
702 }
Bab()
Constructor.
Definition: BonCbc.cpp:70
int getIntParameter(const IntParameter &p) const
Return value of integer parameter.
Behavior of the algorithm in the case of a failure.
int nObjects_
number of objects.
Definition: BonCbc.hpp:124
double bestObj_
objValue of MIP
Definition: BonCbc.hpp:106
Max number of failures in a branch.
void initialize(BabSetupBase &b)
Initialize the method (get options)
Definition: BonDiver.cpp:440
Ipopt::SmartPtr< TMINLP > tminlp()
return pointer to tminlp_.
void setCbcModel(CbcModel *cbc_model)
Method for setting CbcModel, which is used to get statusOfSearch.
const vector< OsiObject * > & objects() const
Access to extra objects.
double getNewCutoffDecr()
Are there a numerical difficulties?
void setObjects(OsiObject **objects, int nObjects)
Set objects.
Depth First Search.
void initialize(BabSetupBase &b)
Initialize the method (get options)
Definition: BonDiver.cpp:750
static bool BonminInteruptedOnce
Definition: BonCbc.cpp:46
int mipIterationCount_
get total number of iterations in last mip solved.
Definition: BonCbc.hpp:114
const double * getDownPsCosts() const
Get number of columns.
This class chooses a variable to branch on.
int num
Number of SOS constraints.
Definition: BonTMINLP.hpp:75
CoinMessageHandler * modelHandler_
Message handler for CbcModel.
Definition: BonCbc.hpp:118
MipStatuses mipStatus_
Status of the mip solved.
Definition: BonCbc.hpp:104
const TMINLP2TNLP * problem() const
get pointer to the TMINLP2TNLP adapter
const double * getUpPsCosts() const
Get number of columns.
This is class provides an Osi interface for a Mixed Integer Linear Program expressed as a TMINLP (so ...
Stop if relative gap is less than this.
virtual const SosInfo * sosConstraints() const =0
double maxLocalSearchTime_
maximum time for local searches
int has_x_init()
xInit has been set?
Spetial option in particular for Cbc.
Same as DfsDiveFromBest, but after a prescribed number of integer solution are found switch to best-b...
There is a CbcObject in the model which is not understood by Bonmin.
Definition: BonExitCodes.hpp:9
void setComparisonBound(const CbcCompareBase &val)
Set comparison method when closing bound.
Definition: BonDiver.hpp:402
void initialize(BabSetupBase &b)
Initialize the method (get options)
Definition: BonDiver.cpp:184
double * bestSolution_
Stores the solution of MIP.
Definition: BonCbc.hpp:101
Number of candidates for strong branching.
CbcModel model_
CbcModel used to solve problem.
Definition: BonCbc.hpp:116
Class to store sos constraints for model.
Definition: BonTMINLP.hpp:72
double continuousRelaxation_
Continuous relaxation of the problem.
Definition: BonCbc.hpp:110
void generateCuts(const OsiSolverInterface &solver, OsiCuts &cs, const CglTreeInfo info=CglTreeInfo())
int numNodes_
Number of nodes enumerated.
Definition: BonCbc.hpp:112
const int * getBranchingDirections() const
get prefered branching directions
const std::vector< double > & bestSolution2() const
get the best solution computed with alternative objective function.
Definition: BonAuxInfos.hpp:71
virtual int getNumCols() const
Get number of columns.
void setup_global_time_limit(double time_limit)
Setup for a global time limit for solver.
const int * getPriorities() const
Get priorities on integer variables.
void setDiver(CbcDfsDiver *diver)
Set the dfs diver to use.
Definition: BonDiver.hpp:379
virtual void operator()(BabSetupBase &s)
operator() performs the branchAndBound
Definition: BonCbc.cpp:98
Dynamic strategy, see CbcBranchActual.hpp for explanations.
Minimum reliability before trust pseudo-costs.
From a TMINLP, this class adapts to another TMINLP where the original objective is transformed into a...
const Bonmin::TNLPSolver * solver() const
TreeTraversal treeTraversalMethod()
Method used to traverse tree.
virtual void replaceIntegers(OsiObject **objects, int numberObjects)
virtual callback function to eventually modify objects for integer variable (replace with user set)...
Definition: BonCbc.hpp:84
CbcModel * OAModel
Definition: BonCbc.cpp:36
Class to perform OA in its classical form.
int * starts
For 0 &lt;= i &lt; nums, start[i] gives the indice of indices and weights arrays at which the description o...
Definition: BonTMINLP.hpp:86
void assignLpInterface(OsiSolverInterface *si)
Assign an OsiTMINLPInterface.
static CbcModel * currentBranchModel
Definition: BonCbc.cpp:34
A class to have all elements necessary to setup a branch-and-bound.
limit on number of integer feasible solution.
virtual void finalize_solution(TMINLP::SolverReturn status, Ipopt::Index n, const Ipopt::Number *x, Ipopt::Number obj_value)=0
This method is called when the algorithm is complete so the TNLP can store/write the solution...
SolverReturn
Return statuses of algorithm.
Definition: BonTMINLP.hpp:64
virtual bool setWarmStart(const CoinWarmStart *warm, Ipopt::SmartPtr< TMINLP2TNLP > tnlp)=0
Set the warm start in the solver.
static void signal_handler(int whichSignal)
Definition: BonCbc.cpp:47
Problem has been proven to be infeasible.
Definition: BonCbc.hpp:24
bool hasContinuedOnAFailure()
Did we continue on a failure.
A more elaborate diving class.
Definition: BonDiver.hpp:199
OsiChooseVariable * branchingMethod()
branching method to use.
void fint fint fint fint fint fint fint fint fint fint real real real real real real real real * s
int * priorities
priorities of sos constraints.
Definition: BonTMINLP.hpp:79
double bestObj2() const
return objective value of the best solution computed with alternative objective function.
Definition: BonAuxInfos.hpp:77
Display information every logIntervval nodes.
char * types
Type of sos.
Definition: BonTMINLP.hpp:77
#define CUTOFF_TOL
Definition: BonCbc.cpp:31
Max number of consecutive infeasible problem in a branch before fathoming.
dive from top node of the heap untill it gets to a leaf of the tree.
Bonmin::OACutGenerator2 * currentOA
Definition: BonCbc.cpp:35
Consider or not SOS constraints.
Log level for root relaxation.
NodeComparison & nodeComparisonMethod()
Method used to compare nodes.
double bestBound_
best known (lower) bound.
Definition: BonCbc.hpp:108
void setModel(Ipopt::SmartPtr< TMINLP > tminlp)
Set the model to be solved by interface.
void setBabPtr(Bab *babPtr)
Set pointer to the branch-and-bound algorithm (to access CbcModel).
Definition: BonBabInfos.hpp:38
Number of cut passes at nodes.
int * indices
indices of elements belonging to the SOS.
Definition: BonTMINLP.hpp:88
virtual CoinWarmStart * getWarmStart(Ipopt::SmartPtr< TMINLP2TNLP > tnlp) const =0
Get the warm start form the solver.
bool BonminAbortAll
Definition: BonCbc.cpp:37
virtual ~Bab()
destructor.
Definition: BonCbc.cpp:85
We will throw this error when a problem is not solved.
An integer solution to the problem has been found.
Definition: BonCbc.hpp:25
OsiTMINLPInterface * nonlinearSolver()
Pointer to the non-linear solver used.
Ipopt::SmartPtr< Ipopt::OptionsList > options()
Acces list of Options.
double getDoubleParameter(const DoubleParameter &p) const
Return value of double parameter.
No feasible solution to the problem is known.
Definition: BonCbc.hpp:27
Optimum solution has been found and its optimality proved.
Definition: BonCbc.hpp:23
OsiSolverInterface * continuousSolver()
Pointer to the continuous solver to use for relaxations.
Base class for OA algorithms.
HeuristicMethods & heuristics()
list of Heuristic methods to use.
dive from top node of the heap with more elaborate strategy (see options doc).
virtual void branchAndBound(BabSetupBase &s)
Perform a branch-and-bound using given setup.
Definition: BonCbc.cpp:105
double bestBound()
return the best known lower bound on the objective value
Definition: BonCbc.cpp:695
Eplore two kids before following on dive.
Number of cut passes at nodes.
Class to do probed diving in the tree.
Definition: BonDiver.hpp:108
void setComparisonDive(const CbcCompareBase &val)
Set comparison method when diving.
Definition: BonDiver.hpp:397
OsiObject ** objects_
OsiObjects of the model.
Definition: BonCbc.hpp:122
CuttingMethods & cutGenerators()
list of cutting planes methods to apply with their frequencies.
Class to do diving in the tree.
Definition: BonDiver.hpp:26
Stop if absolute gap is less than this.
Best guessed integer solution is subtree below, based on pseudo costs.
Bonmin class for passing info between components of branch-and-cuts.
Definition: BonBabInfos.hpp:19
double * weights
weights of the elements of the SOS.
Definition: BonTMINLP.hpp:90