BonDiver.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 : 09/01/2007
9 
10 #include "BonDiver.hpp"
11 #include "CoinFinite.hpp"
12 #include "CbcModel.hpp"
13 #include "CbcConfig.h"
14 #include "BonBabSetupBase.hpp"
15 //#define DIVE_DEBUG
16 namespace Bonmin
17 {
18 
19  /************************************************************************/
20  /* CbcDiver methods */
21  /************************************************************************/
22 
24  CbcDiver::CbcDiver(): CbcTree(),
25  treeCleaning_(false),
26  nextOnBranch_(NULL),
27  stop_diving_on_cutoff_(false)
28  {}
29 
31  CbcDiver::CbcDiver(const CbcDiver &rhs):CbcTree(rhs),
32  treeCleaning_(rhs.treeCleaning_),
33  nextOnBranch_(rhs.nextOnBranch_),
34  stop_diving_on_cutoff_(rhs.stop_diving_on_cutoff_)
35  {}
36 
38  CbcDiver &
40  {
41  if (this != &rhs) {
42  CbcTree::operator=(rhs);
46  }
47  return *this;
48  }
49 
52  {}
53 
55  CbcTree *
57  {
58  return new CbcDiver(*this);
59  }
60 
61 
63  CbcNode *
64  CbcDiver::top() const
65  {
66 #ifdef DIVE_DEBUG
67  std::cout<<"CbcDiver::top"<<std::endl;
68 #endif
69  if (nextOnBranch_ != NULL && !treeCleaning_) {
70  return nextOnBranch_;
71  }
72  else return CbcTree::top();
73  }
74 
76  void
77  CbcDiver::push(CbcNode * x)
78  {
79 #ifdef DIVE_DEBUG
80  std::cout<<"CbcDiver::push"<<std::endl;
81 #endif
82  if (treeCleaning_) return CbcTree::push(x);
83 
84  if (x->branchingObject()->numberBranchesLeft() == x->branchingObject()->numberBranches()) {//Not Backtracking
85  assert(nextOnBranch_==NULL);//Should not happen twice in a row
86  nextOnBranch_ = x;
87  }
88  else
89  CbcTree::push(x);
90  }
91 
93  void
95  {
96 #ifdef DIVE_DEBUG
97  std::cout<<"CbcDiver::pop"<<std::endl;
98 #endif
99  if (nextOnBranch_ != NULL && !treeCleaning_) {
100  nextOnBranch_ = NULL;
101  }
102  else
103  CbcTree::pop();
104  }
106  CbcNode *
107  CbcDiver::bestNode(double cutoff)
108  {
109 #ifdef DIVE_DEBUG
110  std::cout<<"CbcDiver::bestNode"<<std::endl;
111 #endif
112  if (nextOnBranch_ != NULL && !treeCleaning_) {
113  if (nextOnBranch_->objectiveValue() < cutoff) {
114  if (stop_diving_on_cutoff_ && nextOnBranch_->guessedObjectiveValue() >= cutoff) {
115  //printf("Stopping dive %g %g\n", nextOnBranch_->objectiveValue(), nextOnBranch_->guessedObjectiveValue());
116  CbcTree::push(nextOnBranch_);
117  nextOnBranch_ = NULL;
118  return CbcTree::bestNode(cutoff);
119  }
120  //printf("Diving!! %g %g\n", nextOnBranch_->objectiveValue(), nextOnBranch_->guessedObjectiveValue());
121  CbcNode * ret_val = nextOnBranch_;
122  nextOnBranch_ = NULL;
123  return ret_val;
124  }
125  assert(true && "We did not think we get here.");
126  CbcTree::push(nextOnBranch_);//For safety
127  nextOnBranch_ = NULL;
128  }
129  return CbcTree::bestNode(cutoff);
130  }
131 
132 
135  {
136  return (CbcTree::empty() && (nextOnBranch_ == NULL) );
137  }
138 
142  void
143  CbcDiver::cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective)
144  {
145  if (nextOnBranch_ != NULL)
146  CbcTree::push(nextOnBranch_);
147  nextOnBranch_=NULL;
148  treeCleaning_ = true;
149  CbcTree::cleanTree(model,cutoff, bestPossibleObjective);
150  treeCleaning_ = false;
151  }
152 
154  double
156  {
157  double bestPossibleObjective = (nextOnBranch_ != NULL) ? nextOnBranch_->objectiveValue() : 1e100;
158  for (unsigned int i = 0 ; i < nodes_.size() ; i++) {
159  if (nodes_[i] == NULL) continue;
160  const double & obj = nodes_[i]->objectiveValue();
161  if (obj < bestPossibleObjective) {
162  bestPossibleObjective = obj;
163  }
164  }
165  return bestPossibleObjective;
166  }
167 
168  void
170  {
171  roptions->SetRegisteringCategory("Diving options", RegisteredOptions::UndocumentedCategory);
172  roptions->AddStringOption2(
173  "stop_diving_on_cutoff",
174  "Flag indicating whether we stop diving based on guessed feasible objective and the current cutoff",
175  "no",
176  "no", "",
177  "yes", "");
178  roptions->setOptionExtraInfo("stop_diving_on_cutoff", 63);
179 
180  }
181 
183  void
185  {
186  b.options()->GetBoolValue("stop_diving_on_cutoff", stop_diving_on_cutoff_,
187  b.prefix());
188  }
189 
190 
191  /************************************************************************/
192  /* CbcProbedDiver methods */
193  /************************************************************************/
194 
197  treeCleaning_(false),
198  nextOnBranch_(NULL),
199  candidateChild_(NULL),
200  stop_diving_on_cutoff_(false)
201  {}
202 
205  treeCleaning_(rhs.treeCleaning_),
206  nextOnBranch_(rhs.nextOnBranch_),
207  candidateChild_(rhs.candidateChild_),
208  stop_diving_on_cutoff_(rhs.stop_diving_on_cutoff_)
209  {}
210 
214  {
215  if (this != &rhs) {
216  CbcTree::operator=(rhs);
221  }
222  return *this;
223  }
224 
227  {}
228 
230  CbcTree *
232  {
233  return new CbcProbedDiver(*this);
234  }
235 
236 
238  CbcNode *
240  {
241 #ifdef DIVE_DEBUG
242  std::cout<<"CbcProbedDiver::top"<<std::endl;
243 #endif
244  if (nextOnBranch_ != NULL && !treeCleaning_) {
245  return nextOnBranch_;
246  }
247  else if(candidateChild_ != NULL && !treeCleaning_){
248  return candidateChild_;
249  }
250  else return CbcTree::top();
251  }
252 
254  void
256  {
257 #ifdef DIVE_DEBUG
258  std::cout<<"CbcProbedDiver::push"<<std::endl;
259 #endif
260  if (treeCleaning_) return CbcTree::push(x);
261 
262  if (x->branchingObject()->numberBranchesLeft() == x->branchingObject()->numberBranches()) {
263  //Not Backtracking
264  if(nextOnBranch_ == NULL && candidateChild_ == NULL){
265 #ifdef DIVE_DEBUG
266  printf("Putting parent %i. objective value %g\n", x, x->objectiveValue());
267 #endif
268  nextOnBranch_ = x;
269  return;
270  }
271  if(candidateChild_ == NULL){
272 #ifdef DIVE_DEBUG
273  printf("Putting first kid %i. objective value %g\n", x, x->objectiveValue());
274 #endif
275  candidateChild_ = x;
276  return;}
277 #ifdef DIVE_DEBUG
278  printf("Putting second kid %i. objective value %g\n", x, x->objectiveValue());
279 #endif
280  // If we get here we have two nodes follow on the best one and put the other on the tree
281  if(comparison_.compareNodes(x,candidateChild_)){// Follow on candidateChild_
282 #ifdef DIVE_DEBUG
283  printf("first child %i is found better.\n", x);
284 #endif
286  CbcTree::push(x);
287  candidateChild_ = NULL;
288  return;
289  }
290  else {// Follow on x
291 #ifdef DIVE_DEBUG
292  printf("second child %i is found better\n", x);
293 #endif
294  nextOnBranch_ = x;
295  CbcTree::push(candidateChild_);
296  candidateChild_ = NULL;
297  return;
298  }
299  }
300  else {
301 #ifdef DIVE_DEBUG
302  printf("Putting back parent %i.\n",x);
303 #endif
304  if(nextOnBranch_ != NULL){
305 #ifdef DIVE_DEBUG
306  printf("Putting nextOnBranch_ in candidateChild_.\n");
307 #endif
308  assert(candidateChild_ == NULL);
310  }
311  nextOnBranch_ = x;
312  return;
313  //CbcTree::push(x);
314  }
315  }
317  void
319  {
320 #ifdef DIVE_DEBUG
321  std::cout<<"CbcProbedDiver::pop"<<std::endl;
322 #endif
323  if (nextOnBranch_ != NULL && !treeCleaning_) {
324  nextOnBranch_ = NULL;
325  }
326  else if(candidateChild_ != NULL && !treeCleaning_){
327  candidateChild_ = NULL;
328  }
329  else
330  CbcTree::pop();
331  }
333  CbcNode *
335  {
336 #ifdef DIVE_DEBUG
337  std::cout<<"CbcProbedDiver::bestNode"<<std::endl;
338 #endif
339  if (nextOnBranch_ != NULL && !treeCleaning_) {
340  if (nextOnBranch_->objectiveValue() < cutoff) {
341  if (stop_diving_on_cutoff_ && nextOnBranch_->guessedObjectiveValue() >= cutoff) {
342 #ifdef DIVE_DEBUG
343  printf("Stopping dive %g %g\n", nextOnBranch_->objectiveValue(), nextOnBranch_->guessedObjectiveValue());
344 #endif
345  CbcTree::push(nextOnBranch_);
346  nextOnBranch_ = NULL;
347  //Also have to cleanup candidateChild_
348  CbcTree::push(candidateChild_);
349  candidateChild_ = NULL;
350  return CbcTree::bestNode(cutoff);
351  }
352 #ifdef DIVE_DEBUG
353  printf("Diving on %i. obj=%g guesses=%g\n", nextOnBranch_,
354  nextOnBranch_->objectiveValue(),
355  nextOnBranch_->guessedObjectiveValue());
356 #endif
357  CbcNode * ret_val = nextOnBranch_;
358  nextOnBranch_ = NULL;
359  return ret_val;
360  }
361  assert(true && "Should not get here.");
362  CbcTree::push(nextOnBranch_);//For safety
363  nextOnBranch_ = NULL;
364  }
365  else if(candidateChild_ != NULL && ! treeCleaning_){
366 #ifdef DIVE_DEBUG
367  printf("brother was infeasible!!\n``");
368 #endif
369  if(candidateChild_->objectiveValue() < cutoff) {
370  if(stop_diving_on_cutoff_ && candidateChild_->guessedObjectiveValue() >= cutoff) {
371 #ifdef DIVE_DEBUG
372  printf("Stopping dive %g %g\n", candidateChild_->objectiveValue(), candidateChild_->guessedObjectiveValue());
373 #endif
374  CbcTree::push(candidateChild_);
375  candidateChild_ = NULL;
376  return CbcTree::bestNode(cutoff);
377  }
378 #ifdef DIVE_DEBUG
379  printf("Diving on %i. obj=%g guessed=%g\n",
381  candidateChild_->objectiveValue(),
382  candidateChild_->guessedObjectiveValue());
383 #endif
384  CbcNode * ret_val = candidateChild_;
385  candidateChild_ = NULL;
386  return ret_val;
387  }
388  assert(true && "Should not get here.");
389  }
390  CbcNode * ret_val = CbcTree::bestNode(cutoff);
391 #ifdef DIVE_DEBUG
392  printf("Picking top of the heap node %i", ret_val);
393 #endif
394  return ret_val;
395  }
396 
397 
400  {
401  return (CbcTree::empty() && (nextOnBranch_ == NULL) && (candidateChild_ == NULL) );
402  }
403 
407  void
408  CbcProbedDiver::cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective)
409  {
410  if (nextOnBranch_ != NULL)
411  CbcTree::push(nextOnBranch_);
412  if (candidateChild_ != NULL)
413  CbcTree::push(candidateChild_);
414  nextOnBranch_=NULL;
415  candidateChild_ = NULL;
416  treeCleaning_ = true;
417  CbcTree::cleanTree(model,cutoff, bestPossibleObjective);
418  treeCleaning_ = false;
419  }
420 
422  double
424  {
425  double bestPossibleObjective = (nextOnBranch_ != NULL) ? nextOnBranch_->objectiveValue() : 1e100;
426  if(candidateChild_ != NULL && candidateChild_->objectiveValue() < bestPossibleObjective )
427  bestPossibleObjective = candidateChild_->objectiveValue();
428  for (unsigned int i = 0 ; i < nodes_.size() ; i++) {
429  if (nodes_[i] == NULL) continue;
430  const double & obj = nodes_[i]->objectiveValue();
431  if (obj < bestPossibleObjective) {
432  bestPossibleObjective = obj;
433  }
434  }
435  return bestPossibleObjective;
436  }
437 
439  void
441  {
442  b.options()->GetBoolValue("stop_diving_on_cutoff", stop_diving_on_cutoff_,
443  b.prefix());
444  }
445 
446  /************************************************************************/
447  /* CbcDfsDiver methods */
448  /************************************************************************/
451  treeCleaning_(false),
452  dive_(),
453  diveListSize_(0),
454  divingBoardDepth_(-1),
455  cutoff_(1e100),
456  nBacktracks_(0),
457  maxDepthBFS_(4),
458  maxDiveBacktracks_(2),
459  maxDiveDepth_(COIN_INT_MAX),
460  mode_(Enlarge)
461  {}
462 
464  CbcDfsDiver::CbcDfsDiver(const CbcDfsDiver &rhs):CbcTree(rhs),
465  treeCleaning_(rhs.treeCleaning_),
466  dive_(rhs.dive_),
467  diveListSize_(rhs.diveListSize_),
468  divingBoardDepth_(rhs.divingBoardDepth_),
469  cutoff_(rhs.cutoff_),
470  nBacktracks_(rhs.nBacktracks_),
471  maxDepthBFS_(rhs.maxDepthBFS_),
472  maxDiveBacktracks_(rhs.maxDiveBacktracks_),
473  maxDiveDepth_(rhs.maxDiveDepth_),
474  mode_(rhs.mode_)
475  {}
477  CbcDfsDiver &
479  {
480  if (this != &rhs) {
481  CbcTree::operator=(rhs);
483  dive_ = rhs.dive_;
486  cutoff_ = rhs.cutoff_;
491  mode_ = rhs.mode_;
492  }
493  return *this;
494  }
495 
498  {}
499 
501  CbcTree *
503  {
504  return new CbcDfsDiver(*this);
505  }
506 
508  CbcNode *
510  {
511  if (treeCleaning_) return CbcTree::top();
512 #ifdef DIVE_DEBUG
513  std::cout<<"CbcDfsDiver::top"<<std::endl;
514 #endif
516  assert(dive_.empty());
517  CbcTree::top();
518  }
519  if (diveListSize_) {
520  return dive_.front();
521  }
522  else return CbcTree::top();
523  }
524 
526  void
527  CbcDfsDiver::push(CbcNode * x)
528  {
529  if (treeCleaning_) return CbcTree::push(x);
530 #ifdef DIVE_DEBUG
531  std::cout<<"CbcDfsDiver::push"<<std::endl;
532 #endif
534  CbcTree::push(x);
535  assert(dive_.empty());
536  return;
537  }
538  //Always push on dive;
539  dive_.push_front(x);
540  diveListSize_++;
541 #ifdef DIVE_DEBUG
542  printf("diveListSize_ = %i == %u = dive_.size()\n",diveListSize_, dive_.size());
543  assert(diveListSize_ == dive_.size());
544 #endif
545  }
546 
548  void
550  {
551  if (treeCleaning_) return CbcTree::pop();
552 #ifdef DIVE_DEBUG
553  std::cout<<"CbcDfsDiver::pop"<<std::endl;
554 #endif
556  assert(dive_.empty());
557  }
558  if (!dive_.empty()) {
559  dive_.pop_front();
560  diveListSize_--;
561  }
562  else
563  CbcTree::pop();
564  }
565 
567  CbcNode *
568  CbcDfsDiver::bestNode(double cutoff)
569  {
570 #ifdef DIVE_DEBUG
571  std::cout<<"CbcDfsDiver::bestNode"<<std::endl;
572 #endif
573  if (treeCleaning_) return CbcTree::bestNode(cutoff);
574 #ifdef DIVE_DEBUG
575  for (unsigned int i = 0 ; i < nodes_.size() ; i++) {
576  if (nodes_[i]->objectiveValue() >= cutoff)
577  std::cerr<<"CbcDfsDiver::bestNode"<<std::endl
578  <<nodes_[i]->objectiveValue()<<", "<<cutoff<<std::endl;
579  assert(nodes_[i]->objectiveValue() < cutoff);
580  }
581 #endif
582  if (mode_ == CbcDfsDiver::Enlarge) {
583  if (diveListSize_ == 0)
585  else {
586  CbcNode * node = dive_.back();
587  assert(node != NULL);
588  if (node->depth() > maxDepthBFS_) {
589  //Switch mode to Diving
591  }
592  else {
593  //pop and return node;
594  dive_.pop_back();
595  diveListSize_ --;
596  return node;
597  }
598  }
599  }
601  assert(dive_.empty());
602  CbcTree::bestNode(cutoff);
603  }
605  CbcNode * node = NULL;
606  while (diveListSize_ > 0) {
607 #ifdef DIVE_DEBUG
608  std::cerr<<"CbcDfsDiver::bestNode"
609  <<", examining node"<<std::endl;
610 #endif
611  assert(!dive_.empty());
612  node = dive_.front();
613  dive_.pop_front();
614  diveListSize_ --;
615  assert(node);
616  assert((node->depth() - divingBoardDepth_) <= maxDiveDepth_);
617  if (node->objectiveValue() > cutoff) {//throw away node for now just put it on the heap as deleting a node is
618  //more complicated than that (has to delete nodeInfo, cuts...)
619 #ifdef DIVE_DEBUG
620  std::cout<<"CbcDfsDiver::bestNode"
621  <<", node above cutoff"<<std::endl;
622 #endif
623  CbcTree::push(node);
624  node = NULL;
625  nBacktracks_++;
626  }
627  else if (0 && node->guessedObjectiveValue() > cutoff) {//Put it on the real heap
628 #ifdef DIVE_DEBUG
629  std::cout<<"CbcDfsDiver::bestNode"
630  <<", node estimates "<<node->guessedObjectiveValue()<<"above cutoff"
631  <<cutoff<<std::endl;
632 #endif
633  CbcTree::push(node);
634  nBacktracks_++;
635  node = NULL;
636  }
637  else if ((node->depth() - divingBoardDepth_) > maxDiveDepth_) {//Put it on the real heap
638 #ifdef DIVE_DEBUG
639  std::cout<<"CbcDfsDiver::bestNode"
640  <<", node too deep"<<std::endl;
641 #endif
642  CbcTree::push(node);
643  nBacktracks_++;
644  node = NULL;
645  }
646  else if (node->branchingObject()->numberBranchesLeft() < node->branchingObject()->numberBranches()) {//Backtracking
647  nBacktracks_++;
648 #ifdef DIVE_DEBUG
649  std::cout<<"CbcDfsDiver::bestNode"
650  <<", backtracking"<<std::endl;
651 #endif
652  }
653  if (nBacktracks_ >= maxDiveBacktracks_) {//Push all the node in dive_ onto nodes_
654 #ifdef DIVE_DEBUG
655  std::cout<<"CbcDfsDiver::bestNode"
656  <<", maximum number of backtracks attained emptying dive_"<<std::endl;
657 #endif
658  pushDiveOntoHeap(-COIN_DBL_MAX);
659  if (node != NULL) CbcTree::push(node);
660  node = NULL;
661  }
662  if (node != NULL)
663  return node;
664  }
665  assert(node == NULL);
666  assert(dive_.empty());
667  assert(diveListSize_ == 0);
668  node = CbcTree::bestNode(cutoff);
669  divingBoardDepth_ = node->depth();
670  nBacktracks_ = 0;
671  return node;
672  }
673 
674 
675  void CbcDfsDiver::pushDiveOntoHeap(double cutoff)
676  {
677  while (!dive_.empty() ){//&& dive_.front()->objectiveValue() >= cutoff) {
678  CbcTree::push(dive_.front());
679  dive_.pop_front();
680  diveListSize_--;
681  }
682  for (std::list<CbcNode *>::iterator i = dive_.begin() ; i != dive_.end();
683  i++) {
684  assert(*i != NULL);
685  }
686  }
689  {
690  return (CbcTree::empty() && dive_.empty());
691  }
692 
696  void
697  CbcDfsDiver::cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective)
698  {
699 #ifdef DIVE_DEBUG
700  std::cout<<"CbcDfsDiver::cleanTree"<<std::endl;
701  std::cout<<"cutoff: "<<cutoff<<std::endl;
702 #endif
703  pushDiveOntoHeap(cutoff);
704  treeCleaning_ = true;
705  CbcTree::cleanTree(model,cutoff, bestPossibleObjective);
706  treeCleaning_ = false;
707  }
708 
710  double
712  {
713 #ifdef DIVE_DEBUG
714  std::cout<<"CbcDfsDiver::getBestPossibleObjective"<<std::endl;
715 #endif
716  double bestPossibleObjective = CbcTree::empty() ? COIN_DBL_MAX : CbcTree::getBestPossibleObjective();
717  for (std::list<CbcNode *>::iterator i = dive_.begin() ; i != dive_.end() ; i++) {
718  if (*i == NULL) continue;
719  const double & obj = (*i)->objectiveValue();
720  if (obj < bestPossibleObjective) {
721  bestPossibleObjective = obj;
722  }
723  }
724  return bestPossibleObjective;
725  }
726 //#ifdef COIN_HAS_BONMIN
728  void
730  {
731  roptions->SetRegisteringCategory("Diving options", RegisteredOptions::UndocumentedCategory);
732  roptions->AddLowerBoundedIntegerOption("max_backtracks_in_dive",
733  "Set the number of backtracks in a dive when using dfs-dive tree search"
734  "strategy.",
735  0,5,
736  "");
737  roptions->setOptionExtraInfo("max_backtracks_in_dive",27);
738 
739  roptions->AddLowerBoundedIntegerOption("max_dive_depth",
740  "When using dfs-dive search. Maximum depth to go to from the diving "
741  "board (node where the diving started.",
742  0,COIN_INT_MAX,
743  "");
744  roptions->setOptionExtraInfo("max_dive_depth",27);
745 
746  }
747 
749  void
751  {
752  b.options()->GetIntegerValue("max_dive_depth", maxDiveDepth_,b.prefix());
753  b.options()->GetIntegerValue("max_backtracks_in_dive", maxDiveBacktracks_,b.prefix());
754  }
755 //#endif
756 
759  void
761  {
762  if (newMode != mode_) {
763  mode_ = newMode;
764  //Empty heap
765  pushDiveOntoHeap(-COIN_DBL_MAX);
766  nBacktracks_ = maxDiveBacktracks_ -1;//Force to start a new dive
767 #ifdef DIVE_DEBUG
768  std::cout<<"CbcDfsDiver::setComparisonMode"
769  <<std::endl;
770  switch (mode_) {
771  case Enlarge:
772  std::cout<<"Enlarge"<<std::endl;
773  break;
774  case FindSolutions:
775  std::cout<<"FindSolutions"<<std::endl;
776  break;
777  case CloseBound:
778  std::cout<<"CloseBound"<<std::endl;
779  break;
780  case LimitTreeSize:
781  std::cout<<"LimitTreeSize"<<std::endl;
782  break;
783  }
784 #endif
785  CbcTree::setComparison(*comparison_.test_);
786  }
787  }
788 
789 
790 
791  // This allows any method to change behavior as it is called
792  // after each solution
793  bool
794  DiverCompare::newSolution(CbcModel * model)
795  {
796  assert(diver_);
797 #ifdef DIVE_DEBUG
798  std::cout<<"CbcDfsDiver::newSolution"
799  <<std::endl;
800  std::cout<<"Found "<<model->getSolutionCount()<<" solutions"<<std::endl;
801 #endif
802  bool r_value = false;
805  r_value = true;}
806  if (model->getSolutionCount() >= numberSolToStopDive_ && diver_->getComparisonMode() == CbcDfsDiver::FindSolutions) {
808  r_value = true;
809  }
810  return r_value;
811  }
812 
814  bool
815  DiverCompare::test (CbcNode * x, CbcNode * y)
816  {
817  assert(diver_);
818  assert(comparisonDive_);
819  assert(comparisonBound_);
821  if (mode == CbcDfsDiver::FindSolutions) {
822  return comparisonDive_->test(x,y);
823  }
824  else if (mode == CbcDfsDiver::CloseBound) {
825  return comparisonBound_->test(x,y);
826  }
827  else if (mode == CbcDfsDiver::LimitTreeSize) {
828  return comparisonDepth_.test(x,y);
829  }
830  else {
831  throw CoinError("DiverCompare","test"," Unknown mode for comparison.");
832  }
833  }
834 
835 
836  // This Also allows any method to change behavior as it is called
837  // after each solution
838  bool
839  DiverCompare::newSolution(CbcModel * model,
840  double objectiveAtContinuous,
841  int numberInfeasibilitiesAtContinuous)
842  { return false; }
843 
844  // This allows any method to change behavior as it is called
845  // after every 1000 nodes.
846  // Return true if want tree re-sorted
847  bool
848  DiverCompare::every1000Nodes(CbcModel * model,int numberNodes)
849  {
850  assert(diver_);
853  return true;
854  }
855  return false;
856  }
857 
858 }/* Ends namespace Bonmin.*/
859 
virtual ~CbcDfsDiver()
Destructor.
Definition: BonDiver.cpp:497
void initialize(BabSetupBase &b)
Initialize the method (get options)
Definition: BonDiver.cpp:440
void setComparisonMode(ComparisonModes newMode)
Changes the mode of comparison of the tree for &quot;safety reasons&quot; if the mode really changes we always ...
Definition: BonDiver.cpp:760
bool treeCleaning_
Say if we are cleaning the tree (then only call CbcTree functions).
Definition: BonDiver.hpp:174
CbcDiver()
Default constructor.
Definition: BonDiver.cpp:24
void initialize(BabSetupBase &b)
Initialize the method (get options)
Definition: BonDiver.cpp:750
virtual bool empty()
Test if empty.
Definition: BonDiver.cpp:134
CbcNode * candidateChild_
Candidate child explored.
Definition: BonDiver.hpp:178
virtual bool every1000Nodes(CbcModel *model, int numberNodes)
Called 1000 nodes.
Definition: BonDiver.cpp:848
CbcDiver & operator=(const CbcDiver &rhs)
Assignment operator.
Definition: BonDiver.cpp:39
virtual void push(CbcNode *x)
Add node to the heap.
Definition: BonDiver.cpp:77
double cutoff_
Last reported cutoff.
Definition: BonDiver.hpp:289
std::list< CbcNode * > dive_
List of the nodes in the current dive.
Definition: BonDiver.hpp:283
virtual ~CbcDiver()
Destructor.
Definition: BonDiver.cpp:51
CbcCompareBase * comparisonDive_
Comparison method used in diving mode.
Definition: BonDiver.hpp:414
void initialize(BabSetupBase &b)
Initialize the method (get options)
Definition: BonDiver.cpp:184
bool treeCleaning_
Say if we are cleaning the tree (then only call CbcTree functions).
Definition: BonDiver.hpp:95
virtual CbcNode * top() const
Return top node (next node to process.*/.
Definition: BonDiver.cpp:64
virtual CbcNode * top() const
Return top node (next node to process.*/.
Definition: BonDiver.cpp:239
virtual void push(CbcNode *x)
Add node to the heap.
Definition: BonDiver.cpp:527
int nBacktracks_
number of backtracks done in current dive.
Definition: BonDiver.hpp:291
int treeCleaning_
Flag to say that we are currently cleaning the tree and should work only on the heap.
Definition: BonDiver.hpp:281
virtual void pop()
Remove the top node of the heap.
Definition: BonDiver.cpp:549
CbcNode * nextOnBranch_
Noext node on the branch.
Definition: BonDiver.hpp:97
virtual double getBestPossibleObjective()
Get best possible objective function in the tree.
Definition: BonDiver.cpp:423
A class to have all elements necessary to setup a branch-and-bound.
virtual bool empty()
Test if empty.
Definition: BonDiver.cpp:688
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register the options of the method.
Definition: BonDiver.cpp:729
virtual CbcTree * clone() const
Virtual copy constructor.
Definition: BonDiver.cpp:56
CbcDfsDiver * diver_
Pointer to the CbcDfsDiver handling the tree.
Definition: BonDiver.hpp:408
virtual CbcNode * bestNode(double cutoff)
Remove the best node from the heap and return it.
Definition: BonDiver.cpp:568
int maxDiveBacktracks_
Maximum number of backtrack in one dive.
Definition: BonDiver.hpp:297
bool stop_diving_on_cutoff_
Flag indicating if we want to stop diving based on the guessed objective value and the cutoff value ...
Definition: BonDiver.hpp:181
virtual CbcNode * bestNode(double cutoff)
Remove the best node from the heap and return it.
Definition: BonDiver.cpp:334
int maxDepthBFS_
Maximum depth until which we&#39;ll do a bredth-first-search.
Definition: BonDiver.hpp:295
virtual void cleanTree(CbcModel *model, double cutoff, double &bestPossibleObjective)
Prune the tree using an objective function cutoff.
Definition: BonDiver.cpp:697
virtual bool newSolution(CbcModel *model)
Called after each new solution.
Definition: BonDiver.cpp:794
virtual CbcNode * top() const
Return top node (next node to process.*/.
Definition: BonDiver.cpp:509
A more elaborate diving class.
Definition: BonDiver.hpp:199
virtual void cleanTree(CbcModel *model, double cutoff, double &bestPossibleObjective)
Prune the tree using an objective function cutoff.
Definition: BonDiver.cpp:408
CbcDfsDiver()
Default constructor.
Definition: BonDiver.cpp:450
virtual double getBestPossibleObjective()
Get best possible objective function in the tree.
Definition: BonDiver.cpp:155
CbcDfsDiver & operator=(const CbcDfsDiver &rhs)
Assignment operator.
Definition: BonDiver.cpp:478
ComparisonModes getComparisonMode()
get the mode of comparison of the tree.
Definition: BonDiver.hpp:274
ComparisonModes mode_
Current mode of the diving strategy.
Definition: BonDiver.hpp:301
virtual bool test(CbcNode *x, CbcNode *y)
This is test function.
Definition: BonDiver.cpp:815
int numberNodesToLimitTreeSize_
Number of nodes before we command diver_ to limit the tree size.
Definition: BonDiver.hpp:412
At the very beginning we might want to enlarge the tree just a bit.
Definition: BonDiver.hpp:203
CbcProbedDiver()
Default constructor.
Definition: BonDiver.cpp:196
bool stop_diving_on_cutoff_
Flag indicating if we want to stop diving based on the guessed objective value and the cutoff value ...
Definition: BonDiver.hpp:100
CbcProbedDiver & operator=(const CbcProbedDiver &rhs)
Assignment operator.
Definition: BonDiver.cpp:213
virtual void pop()
Remove the top node of the heap.
Definition: BonDiver.cpp:318
virtual CbcTree * clone() const
Virtual copy constructor.
Definition: BonDiver.cpp:231
int divingBoardDepth_
Depth of the node from which diving was started (we call this node the diving board).
Definition: BonDiver.hpp:287
virtual CbcTree * clone() const
Virtual copy constructor.
Definition: BonDiver.cpp:502
virtual void pop()
Remove the top node of the heap.
Definition: BonDiver.cpp:94
CbcCompareBase * comparisonBound_
Comparison method used bound mode.
Definition: BonDiver.hpp:416
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register the options of the method.
Definition: BonDiver.cpp:169
Ipopt::SmartPtr< Ipopt::OptionsList > options()
Acces list of Options.
CbcCompareDepth comparisonDepth_
Comparison method used when limit tree size.
Definition: BonDiver.hpp:418
int numberSolToStopDive_
Number of solution before we command diver_ to stop diving.
Definition: BonDiver.hpp:410
void pushDiveOntoHeap(double cutoff)
Pushes onto heap all the nodes with objective value &gt; cutoff.
Definition: BonDiver.cpp:675
virtual void cleanTree(CbcModel *model, double cutoff, double &bestPossibleObjective)
Prune the tree using an objective function cutoff.
Definition: BonDiver.cpp:143
Class to do probed diving in the tree.
Definition: BonDiver.hpp:108
CbcNode * nextOnBranch_
Next node on the branch.
Definition: BonDiver.hpp:176
virtual bool empty()
Test if empty.
Definition: BonDiver.cpp:399
virtual CbcNode * bestNode(double cutoff)
Remove the best node from the heap and return it.
Definition: BonDiver.cpp:107
virtual ~CbcProbedDiver()
Destructor.
Definition: BonDiver.cpp:226
virtual void push(CbcNode *x)
Add node to the heap.
Definition: BonDiver.cpp:255
return b
Definition: OSdtoa.cpp:1719
Class to do diving in the tree.
Definition: BonDiver.hpp:26
virtual double getBestPossibleObjective()
Get best possible objective function in the tree.
Definition: BonDiver.cpp:711
int diveListSize_
Record dive list size for constant time access.
Definition: BonDiver.hpp:285
const char * prefix() const
Get prefix to use for options.
int maxDiveDepth_
Maximum depth to go from divingBoard.
Definition: BonDiver.hpp:299
void fint fint fint real fint real * x