BonBonminSetup.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/13/2007
9 
10 #include "BonminConfig.h"
11 #include "OsiClpSolverInterface.hpp"
12 
13 #include "BonBonminSetup.hpp"
14 #ifdef BONMIN_CURVATURE_BRANCHING
16 #endif
17 #include "BonChooseVariable.hpp"
18 #include "BonRandomChoice.hpp"
19 #include "BonDiver.hpp"
20 #include "BonQpBranchingSolver.hpp"
21 #include "BonLpBranchingSolver.hpp"
22 
23 //OA machinery
24 #include "BonDummyHeuristic.hpp"
25 #include "BonOACutGenerator2.hpp"
26 #include "BonFpForMinlp.hpp"
27 #include "BonOaFeasChecker.hpp"
28 #include "BonOaNlpOptim.hpp"
29 #include "BonEcpCuts.hpp"
30 
31 #include "BonCbcNode.hpp"
32 #ifdef COIN_HAS_FILTERSQP
33 # include "BonFilterSolver.hpp"
34 #endif
35 
36 //MILP cuts
37 #include "CglGomory.hpp"
38 #include "CglProbing.hpp"
39 #include "CglKnapsackCover.hpp"
40 #include "CglOddHole.hpp"
41 #include "CglClique.hpp"
42 #include "CglFlowCover.hpp"
43 #include "CglMixedIntegerRounding2.hpp"
44 #include "CglTwomir.hpp"
45 #include "CglPreProcess.hpp"
46 #include "CglLandP.hpp"
47 #include "CglRedSplit.hpp"
49 
51 #include "BonDummyPump.hpp"
52 #include "BonPumpForMinlp.hpp"
53 #include "BonHeuristicRINS.hpp"
55 #include "BonHeuristicFPump.hpp"
60 #include "BonMilpRounding.hpp"
61 //#include "BonInnerApproximation.hpp"
62 namespace Bonmin
63 {
64  BonminSetup::BonminSetup(const CoinMessageHandler * handler):BabSetupBase(handler),algo_(Dummy)
65  {}
66 
68  algo_(other.algo_)
69  {}
70 
72  OsiTMINLPInterface &nlp):
73  BabSetupBase(other, nlp),
74  algo_(other.algo_)
75  {
76  if(algo_ != B_BB){
77  assert(continuousSolver_ == NULL);
78  continuousSolver_ = new OsiClpSolverInterface;
79  int lpLogLevel;
80  options_->GetIntegerValue("lp_log_level",lpLogLevel,prefix_.c_str());
81  if(messageHandler_)
82  continuousSolver_->passInMessageHandler(messageHandler_);
83  continuousSolver_->messageHandler()->setLogLevel(lpLogLevel);
84 
86  // say bound dubious, does cuts at solution
87  OsiBabSolver * extraStuff = new OsiBabSolver(3);
88  continuousSolver_->setAuxiliaryInfo(extraStuff);
89  delete extraStuff;
90  }
91  }
93  OsiTMINLPInterface &nlp,
94  const std::string &prefix):
95  BabSetupBase(other, nlp, prefix),
96  algo_(Dummy)
97  {
98  algo_ = getAlgorithm();
99  if (algo_ == B_BB)
100  initializeBBB();
101  else
102  initializeBHyb(true);
103  }
105  {
107 
108  /* Outer Approximation options.*/
112  EcpCuts::registerOptions(roptions);
113  OaNlpOptim::registerOptions(roptions);
115 
116 
118 
119 
120  registerMilpCutGenerators(roptions);
121 
122 
126  DummyPump::registerOptions(roptions);
136 
137  roptions->SetRegisteringCategory("Algorithm choice", RegisteredOptions::BonminCategory);
138  roptions->AddStringOption6("algorithm",
139  "Choice of the algorithm.",
140  "B-BB",
141  "B-BB","simple branch-and-bound algorithm,",
142  "B-OA","OA Decomposition algorithm,",
143  "B-QG","Quesada and Grossmann branch-and-cut algorithm,",
144  "B-Hyb","hybrid outer approximation based branch-and-cut,",
145  "B-Ecp","ECP cuts based branch-and-cut a la FilMINT.",
146  "B-iFP","Iterated Feasibility Pump for MINLP.",
147  "This will preset some of the options of bonmin depending on the algorithm choice."
148  );
149  roptions->setOptionExtraInfo("algorithm",127);
150 
151 
152  }
153 
155  void
157  {
159  }
160 
162  void
163  BonminSetup::initialize(Ipopt::SmartPtr<TMINLP> tminlp, bool createContinuousSolver /*= false*/)
164  {
165 
166  use(tminlp);
168  algo_ = getAlgorithm();
169  if (algo_ == B_BB)
170  initializeBBB();
171  else
172  initializeBHyb(createContinuousSolver);
173  }
174 
176  void
177  BonminSetup::initialize(const OsiTMINLPInterface &nlpSi, bool createContinuousSolver /*= false*/)
178  {
179  use(nlpSi);
181  Algorithm algo = getAlgorithm();
182  if (algo == B_BB)
183  initializeBBB();
184  else
185  initializeBHyb(createContinuousSolver);
186  }
187 
189  void
191  {
192  roptions->SetRegisteringCategory("MILP cutting planes in hybrid algorithm", RegisteredOptions::BonminCategory);
193 
194  roptions->AddLowerBoundedIntegerOption("Gomory_cuts",
195  "Frequency (in terms of nodes) for generating Gomory cuts in branch-and-cut.",
196  -100,-5,
197  "If $k > 0$, cuts are generated every $k$ nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
198  "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
199  "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
200  roptions->setOptionExtraInfo("Gomory_cuts",119);
201 #if 0
202  roptions->AddBoundedIntegerOption("probing_cuts",
203  "Frequency (in terms of nodes) for generating probing cuts in branch-and-cut",
204  0,0,0,
205  "If $k > 0$, cuts are generated every $k$ nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
206  "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
207  "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
208  roptions->setOptionExtraInfo("probing_cuts",0);
209 #endif
210  roptions->AddLowerBoundedIntegerOption("cover_cuts",
211  "Frequency (in terms of nodes) for generating cover cuts in branch-and-cut",
212  -100,0,
213  "If $k > 0$, cuts are generated every $k$ nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
214  "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
215  "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
216  roptions->setOptionExtraInfo("cover_cuts",119);
217 
218  roptions->AddLowerBoundedIntegerOption("mir_cuts",
219  "Frequency (in terms of nodes) for generating MIR cuts in branch-and-cut",
220  -100,-5,
221  "If $k > 0$, cuts are generated every $k$ nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
222  "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
223  "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
224  roptions->setOptionExtraInfo("mir_cuts",119);
225  roptions->AddLowerBoundedIntegerOption("2mir_cuts",
226  "Frequency (in terms of nodes) for generating 2-MIR cuts in branch-and-cut",
227  -100,0,
228  "If $k > 0$, cuts are generated every $k$ nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
229  "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
230  "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
231  roptions->setOptionExtraInfo("2mir_cuts",119);
232 
233  roptions->AddLowerBoundedIntegerOption("flow_cover_cuts",
234  "Frequency (in terms of nodes) for generating flow cover cuts in branch-and-cut",
235  -100,-5,
236  "If $k > 0$, cuts are generated every $k$ nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
237  "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
238  "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
239  roptions->setOptionExtraInfo("flow_cover_cuts",119);
240  roptions->AddLowerBoundedIntegerOption("lift_and_project_cuts",
241  "Frequency (in terms of nodes) for generating lift-and-project cuts in branch-and-cut",
242  -100,0,
243  "If $k > 0$, cuts are generated every $k$ nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
244  "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
245  "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
246  roptions->setOptionExtraInfo("lift_and_project_cuts", 119);
247  roptions->AddLowerBoundedIntegerOption("reduce_and_split_cuts",
248  "Frequency (in terms of nodes) for generating reduce-and-split cuts in branch-and-cut",
249  -100,0,
250  "If $k > 0$, cuts are generated every $k$ nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
251  "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
252  "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
253  roptions->setOptionExtraInfo("reduce_and_split_cuts", 119);
254 
255 
256  roptions->AddLowerBoundedIntegerOption("clique_cuts",
257  "Frequency (in terms of nodes) for generating clique cuts in branch-and-cut",
258  -100,-5,
259  "If $k > 0$, cuts are generated every $k$ nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
260  "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
261  "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
262  roptions->setOptionExtraInfo("clique_cuts", 119);
263 
264  }
265 
266 
268  void
270  {
271 
272  int freq;
273 
274  options_->GetIntegerValue("Gomory_cuts", freq,prefix_.c_str());
275 
276  if (freq) {
277  CuttingMethod cg;
278  cg.frequency = freq;
279  CglGomory * gom = new CglGomory;
280  cg.cgl = gom;
281  gom->setLimitAtRoot(5000);
282  gom->setLimit(500);
283  gom->setLargestFactorMultiplier(1e-08);
284  cg.id = "Mixed Integer Gomory";
285  cutGenerators_.push_back(cg);
286  }
287 
288 #if 0
289  options_->GetIntegerValue("probing_cuts",freq,prefix_.c_str());
290  if (freq) {
291  CuttingMethod cg;
292  cg.frequency = freq;
293  CglProbing * probe = new CglProbing;
294  cg.cgl = probe;
295  probe->setUsingObjective(1);
296  probe->setMaxPass(3);
297  probe->setMaxPassRoot(3);
298  // Number of unsatisfied variables to look at
299  probe->setMaxProbe(10);
300  probe->setMaxProbeRoot(50);
301  // How far to follow the consequences
302  probe->setMaxLook(10);
303  probe->setMaxLookRoot(50);
304  probe->setMaxLookRoot(10);
305  // Only look at rows with fewer than this number of elements
306  probe->setMaxElements(200);
307  probe->setRowCuts(3);
308  cg.id = "Probing";
309  cutGenerators_.push_back(cg);
310  }
311 #endif
312 
313  options_->GetIntegerValue("mir_cuts",freq,prefix_.c_str());
314 
315  if (freq) {
316  CuttingMethod cg;
317  cg.frequency = freq;
318  CglMixedIntegerRounding2 * mir = new CglMixedIntegerRounding2;
319  //CglMixedIntegerRounding2 * mir = new CglMixedIntegerRounding2(1, true, 1);
320  cg.cgl = mir;
321  cg.id = "Mixed Integer Rounding";
322  cutGenerators_.push_back(cg);
323  }
324 
325  options_->GetIntegerValue("2mir_cuts",freq,prefix_.c_str());
326 
327  if (freq) {
328  CuttingMethod cg;
329  cg.frequency = freq;
330  CglTwomir * mir2 = new CglTwomir;
331  cg.cgl = mir2;
332  cg.id = "2-MIR";
333  cutGenerators_.push_back(cg);
334  }
335 
336  options_->GetIntegerValue("cover_cuts",freq,prefix_.c_str());
337 
338  if (freq) {
339  CuttingMethod cg;
340  cg.frequency = freq;
341  CglKnapsackCover * cover = new CglKnapsackCover;
342  cg.cgl = cover;
343  cg.id = "Cover";
344  cutGenerators_.push_back(cg);
345  }
346 
347  options_->GetIntegerValue("clique_cuts",freq,prefix_.c_str());
348 
349  if (freq) {
350  CuttingMethod cg;
351  cg.frequency = freq;
352  CglClique * clique = new CglClique;
353  clique->setStarCliqueReport(false);
354  clique->setRowCliqueReport(false);
355  clique->setMinViolation(0.1);
356 
357  cg.cgl = clique;
358  cg.id = "Clique";
359  cutGenerators_.push_back(cg);
360  }
361 
362  options_->GetIntegerValue("flow_cover_cuts",freq,prefix_.c_str());
363 
364  if (freq) {
365  CuttingMethod cg;
366  cg.frequency = freq;
367  CglFlowCover * flow = new CglFlowCover;
368  cg.cgl = flow;
369  cg.id = "Flow Covers";
370  cutGenerators_.push_back(cg);
371  }
372 
373  options_->GetIntegerValue("lift_and_project_cuts",freq,prefix_.c_str());
374 
375  if (freq) {
376  CuttingMethod cg;
377  cg.frequency = freq;
378  CglLandP * landp = new CglLandP;
379  cg.cgl = landp;
380  cg.id = "Lift-and-Project";
381  cutGenerators_.push_back(cg);
382  }
383 
384  options_->GetIntegerValue("reduce_and_split_cuts",freq,prefix_.c_str());
385 
386  if (freq) {
387  CuttingMethod cg;
388  cg.frequency = freq;
389  CglRedSplit * rands = new CglRedSplit;
390  cg.cgl = rands;
391  cg.id = "Reduce-and-Split";
392  cutGenerators_.push_back(cg);
393  }
394  }
395 
396 
397  void
399  {
402  OsiBabSolver extraStuff(2);
403  continuousSolver_->setAuxiliaryInfo(&extraStuff);
404 
406  if (!options_->GetIntegerValue("number_before_trust",intParam_[BabSetupBase::MinReliability],prefix_.c_str())) {
408  std::string o_name = prefix_ + "number_before_trust";
409  options_->SetIntegerValue(o_name.c_str(),intParam_[BabSetupBase::MinReliability],true,true);
410  }
411  if (!options_->GetIntegerValue("number_strong_branch",intParam_[BabSetupBase::NumberStrong],prefix_.c_str())) {
413  std::string o_name = prefix_ + "number_strong_branch";
414  options_->SetIntegerValue(o_name.c_str(),intParam_[BabSetupBase::NumberStrong],true,true);
415  }
416  int varSelection;
417  bool val = options_->GetEnumValue("variable_selection",varSelection,prefix_.c_str());
418  if (!val){// || varSelection == STRONG_BRANCHING || varSelection == RELIABILITY_BRANCHING ) {
419  std::string o_name = prefix_ + "variable_selection";
420  options_->SetStringValue(o_name.c_str(), "nlp-strong-branching",true,true);
421  varSelection = NLP_STRONG_BRANCHING;
422  }
423 
424  switch (varSelection) {
425 #ifdef BONMIN_CURVATURE_BRANCHING
426  case CURVATURE_ESTIMATOR:
427 #endif
428  case QP_STRONG_BRANCHING:
429  case LP_STRONG_BRANCHING:
430  case NLP_STRONG_BRANCHING: {
431  continuousSolver_->findIntegersAndSOS(false);
432  setPriorities();
433  addSos();
434  Ipopt::SmartPtr<StrongBranchingSolver> strong_solver = NULL;
435  BonChooseVariable * chooseVariable = new BonChooseVariable(*this, nonlinearSolver_);
436  chooseVariable->passInMessageHandler(nonlinearSolver_->messageHandler());
437  switch (varSelection) {
438 #ifdef BONMIN_CURVATURE_BRANCHING
439  case CURVATURE_ESTIMATOR:
440  strong_solver = new CurvBranchingSolver(nonlinearSolver_);
441  chooseVariable->setTrustStrongForSolution(false);
442  chooseVariable->setTrustStrongForBound(false);
443  //chooseVariable->setOnlyPseudoWhenTrusted(true);
444  chooseVariable->setOnlyPseudoWhenTrusted(false);
445  break;
446 #endif
447  case QP_STRONG_BRANCHING:
448  chooseVariable->setTrustStrongForSolution(false);
449  strong_solver = new QpBranchingSolver(nonlinearSolver_);
450  // The bound returned from the QP can be wrong, since the
451  // objective is not guaranteed to be an underestimator:
452  chooseVariable->setTrustStrongForBound(false);
453  //chooseVariable->setOnlyPseudoWhenTrusted(true);
454  chooseVariable->setOnlyPseudoWhenTrusted(false);
455  break;
456  case LP_STRONG_BRANCHING:
457  chooseVariable->setTrustStrongForSolution(false);
458  strong_solver = new LpBranchingSolver(this);
459  //chooseVariable->setOnlyPseudoWhenTrusted(true);
460  chooseVariable->setOnlyPseudoWhenTrusted(false);
461  break;
463  chooseVariable->setTrustStrongForSolution(false);
464  chooseVariable->setTrustStrongForBound(true);
465  chooseVariable->setOnlyPseudoWhenTrusted(false);
466  break;
467  }
468  nonlinearSolver_->SetStrongBrachingSolver(strong_solver);
469  branchingMethod_ = chooseVariable;
470  }
471  break;
472  case OSI_SIMPLE:
473  continuousSolver_->findIntegersAndSOS(false);
474  setPriorities();
475  addSos();
476  branchingMethod_ = new OsiChooseVariable(nonlinearSolver_);
477 
478  break;
479  case OSI_STRONG:
480  continuousSolver_->findIntegersAndSOS(false);
481  setPriorities();
482  addSos();
483  branchingMethod_ = new OsiChooseStrong(nonlinearSolver_);
484  break;
485  case RANDOM:
486  continuousSolver_->findIntegersAndSOS(false);
487  setPriorities();
488  addSos();
490  break;
491  //default:
492  //abort();
493  }
494  if (branchingMethod_ != NULL) {
495  branchingMethod_->setNumberStrong(intParam_[NumberStrong]);
496  }
497 
498 
499  Ipopt::Index doHeuristicDiveFractional = false;
500  options()->GetEnumValue("heuristic_dive_fractional",doHeuristicDiveFractional,prefix_.c_str());
501  if(doHeuristicDiveFractional){
502  HeuristicDiveFractional* dive_fractional = new HeuristicDiveFractional(this);
503  HeuristicMethod h;
504  h.heuristic = dive_fractional;
505  h.id = "DiveFractional";
506  heuristics_.push_back(h);
507  }
508 
509  Ipopt::Index doHeuristicDiveVectorLength = false;
510  options()->GetEnumValue("heuristic_dive_vectorLength",doHeuristicDiveVectorLength,prefix_.c_str());
511  if(doHeuristicDiveVectorLength){
512  HeuristicDiveVectorLength* dive_vectorLength = new HeuristicDiveVectorLength(this);
513  HeuristicMethod h;
514  h.heuristic = dive_vectorLength;
515  h.id = "DiveVectorLength";
516  heuristics_.push_back(h);
517  }
518 
519  Ipopt::Index doHeuristicDiveMIPFractional = false;
520  if(!options()->GetEnumValue("heuristic_dive_MIP_fractional",doHeuristicDiveMIPFractional,prefix_.c_str())){
521  doHeuristicDiveMIPFractional = true;
522  std::string o_name = prefix_ + "heuristic_dive_MIP_fractional";
523  options_->SetStringValue(o_name.c_str(), "yes",true,true);
524  }
525  if(doHeuristicDiveMIPFractional){
526  HeuristicDiveMIPFractional* dive_MIP_fractional = new HeuristicDiveMIPFractional(this);
527  HeuristicMethod h;
528  h.heuristic = dive_MIP_fractional;
529  h.id = "DiveMIPFractional";
530  heuristics_.push_back(h);
531  }
532 
533  Ipopt::Index doHeuristicDiveMIPVectorLength = false;
534  options()->GetEnumValue("heuristic_dive_MIP_vectorLength",doHeuristicDiveMIPVectorLength,prefix_.c_str());
535  if(doHeuristicDiveMIPVectorLength){
536  HeuristicDiveMIPVectorLength* dive_MIP_vectorLength = new HeuristicDiveMIPVectorLength(this);
537  HeuristicMethod h;
538  h.heuristic = dive_MIP_vectorLength;
539  h.id = "DiveMIPVectorLength";
540  heuristics_.push_back(h);
541  }
542  Ipopt::Index doHeuristicFPump = false;
543  if(!nonlinearSolver_->model()->hasGeneralInteger() && !options()->GetEnumValue("heuristic_feasibility_pump",doHeuristicFPump,prefix_.c_str())){
544  doHeuristicFPump = true;
545  std::string o_name = prefix_ + "heuristic_feasibility_pump";
546  options_->SetStringValue(o_name.c_str(), "yes",true,true);
547  }
548  if(doHeuristicFPump){
549  HeuristicFPump* feasibility_pump = new HeuristicFPump(this);
550  HeuristicMethod h;
551  h.heuristic = feasibility_pump;
552  h.id = "FPump";
553  heuristics_.push_back(h);
554  }
555 
556  Ipopt::Index doFixAndSolve = false;
557  options()->GetEnumValue("fix_and_solve_heuristic",doFixAndSolve,prefix_.c_str());
558  if(doFixAndSolve){
559  FixAndSolveHeuristic* fix_and_solve = new FixAndSolveHeuristic(this);
560  HeuristicMethod h;
561  h.heuristic = fix_and_solve;
562  h.id = "Fix and Solve";
563  heuristics_.push_back(h);
564  }
565 
566  Ipopt::Index doDummyPump = false;
567  options()->GetEnumValue("dummy_pump_heuristic",doDummyPump,prefix_.c_str());
568  if(doDummyPump){
569  DummyPump* fix_and_solve = new DummyPump(this);
570  HeuristicMethod h;
571  h.heuristic = fix_and_solve;
572  h.id = "Dummy pump";
573  heuristics_.push_back(h);
574  }
575 
576  Ipopt::Index doHeuristicRINS = false;
577  options()->GetEnumValue("heuristic_RINS",doHeuristicRINS,prefix_.c_str());
578  if(doHeuristicRINS){
579  HeuristicRINS* rins = new HeuristicRINS(this);
580  HeuristicMethod h;
581  h.heuristic = rins;
582  h.id = "RINS";
583  heuristics_.push_back(h);
584  }
585 
586  Ipopt::Index doHeuristicLocalBranching = false;
587  options()->GetEnumValue("heuristic_local_branching",doHeuristicLocalBranching,prefix_.c_str());
588  if(doHeuristicLocalBranching){
589  HeuristicLocalBranching* local_branching = new HeuristicLocalBranching(this);
590  HeuristicMethod h;
591  h.heuristic = local_branching;
592  h.id = "LocalBranching";
593  heuristics_.push_back(h);
594  }
595 
596  Ipopt::Index doHeuristicPumpForMinlp = false;
597  options()->GetEnumValue("pump_for_minlp",doHeuristicPumpForMinlp,prefix_.c_str());
598  if(doHeuristicPumpForMinlp){
599  PumpForMinlp * pump = new PumpForMinlp(this);
600  HeuristicMethod h;
601  h.heuristic = pump;
602  h.id = "Pump for MINLP";
603  heuristics_.push_back(h);
604  }
605 
606  Ipopt::Index doHeuristicMilpRounding = false;
607  options()->GetEnumValue("MILP_rounding_heuristic",doHeuristicMilpRounding,prefix_.c_str());
608  if(doHeuristicMilpRounding){
609  MilpRounding * round = new MilpRounding(this);
610  HeuristicMethod h;
611  h.heuristic = round;
612  h.id = "MILP Rounding";
613  heuristics_.push_back(h);
614  }
615  }
616 
617 
618  void
619  BonminSetup::initializeBHyb(bool createContinuousSolver /*= false*/)
620  {
621  double setup_time = -CoinCpuTime();
622  if (createContinuousSolver) {
623  /* Create linear solver */
624  continuousSolver_ = new OsiClpSolverInterface;
625  int lpLogLevel;
626  options_->GetIntegerValue("lp_log_level",lpLogLevel,prefix_.c_str());
627  if(messageHandler_)
628  continuousSolver_->passInMessageHandler(messageHandler_);
629  continuousSolver_->messageHandler()->setLogLevel(lpLogLevel);
631 
632  if(IsValid(linearizer_))//Use user provided linearizer
633  nonlinearSolver_->set_linearizer(linearizer_);
634 
637 
638  // say bound dubious, does cuts at solution
639  OsiBabSolver * extraStuff = new OsiBabSolver(3);
640  continuousSolver_->setAuxiliaryInfo(extraStuff);
641  delete extraStuff;
642  }
643  Algorithm algo = getAlgorithm();
644  std::string prefix = (prefix_ == "bonmin.") ? "" : prefix_;
645  if (algo == B_Hyb) {
646  std::string o_name = prefix_ + "oa_decomposition";
647  options_->SetStringValue(o_name.c_str(),"no", true, true);
648  o_name = prefix_ + "pump_for_minlp";
649  options_->SetStringValue(o_name.c_str(),"yes", true, true);
650  o_name = prefix + "pump_for_minlp.time_limit";
651  options_->SetNumericValue(o_name.c_str(),10, true, true);
652  o_name = prefix + "pump_for_minlp.solution_limit";
653  options_->SetIntegerValue(o_name.c_str(),3, true, true);
654  }
655  else if (algo == B_OA) {
656  std::string o_name = prefix_ + "oa_decomposition";
657  options_->SetStringValue(o_name.c_str(),"yes", true, true);
658  o_name = prefix + "oa_decomposition.time_limit";
659  options_->SetNumericValue(o_name.c_str(),DBL_MAX, true, true);
660  o_name = prefix_ + "pump_for_minlp";
661  options_->SetStringValue(o_name.c_str(),"no", true, true);
662  o_name = prefix + "nlp_solve_frequency";
663  options_->SetIntegerValue(o_name.c_str(), 0, true, true);
664  o_name = prefix + "bb_log_level";
665  options_->SetIntegerValue(o_name.c_str(), 0, true, true);
666  }
667  else if (algo == B_IFP) {
668  std::string o_name = prefix_ + "oa_decomposition";
669  options_->SetStringValue(o_name.c_str(),"no", true, true);
670  o_name = prefix_ + "pump_for_minlp";
671  options_->SetStringValue(o_name.c_str(),"yes", true, true);
672  o_name = prefix + "pump_for_minlp.time_limit";
673  options_->SetNumericValue(o_name.c_str(),DBL_MAX, true, true);
674  o_name = prefix_ + "nlp_solve_frequency";
675  options_->SetIntegerValue(o_name.c_str(), 0, true, true);
676  o_name = prefix_ + "fp_pass_infeasible";
677  options_->SetStringValue(o_name.c_str(), "yes", true, true);
678  //o_name = prefix_ + "cutoff_decr";
679  //options_->SetNumericValue(o_name.c_str(), 1e-02, true, true);
680  intParam_[BabLogLevel] = 0;
681  }
682  else if (algo==B_QG) {
683  std::string o_name = prefix_ + "oa_decomposition";
684  options_->SetStringValue(o_name.c_str(),"no", true, true);
685  o_name = prefix_ + "pump_for_minlp";
686  options_->SetStringValue(o_name.c_str(),"no", true, true);
687  o_name = prefix_ + "nlp_solve_frequency";
688  options_->SetIntegerValue(o_name.c_str(), 0, true, true);
689  }
690  else if (algo==B_Ecp) {
691  std::string o_name = prefix_ + "oa_decomposition";
692  options_->SetStringValue(o_name.c_str(),"no", true, true);
693  o_name = prefix_ + "pump_for_minlp";
694  options_->SetStringValue(o_name.c_str(),"no", true, true);
695  o_name = prefix_ + "nlp_solve_frequency";
696  options_->SetIntegerValue(o_name.c_str(), 0, true, true);
697  o_name = prefix_ + "filmint_ecp_cuts";
698  options_->SetIntegerValue(o_name.c_str(), 1, true, true);
699  }
700 //#define GREAT_STUFF_FOR_ANDREAS
701 #ifdef GREAT_STUFF_FOR_ANDREAS
702  printf("ToDo: Clean me up in Bab::branchAndBound\n");
703  OsiCuts cuts;
704  nonlinearSolver_->getOuterApproximation(cuts, true, NULL, true);
705  continuousSolver_->applyCuts(cuts);
706 #endif
707 
708 
709  int varSelection;
710  options_->GetEnumValue("variable_selection",varSelection,prefix_.c_str());
711  if (varSelection > RELIABILITY_BRANCHING) {
712  switch (varSelection){
713  case OSI_SIMPLE:
714  continuousSolver_->findIntegersAndSOS(false);
715  setPriorities();
716  addSos();
717  branchingMethod_ = new OsiChooseVariable(nonlinearSolver_);
718 
719  break;
720  case OSI_STRONG:
721  {
722  continuousSolver_->findIntegersAndSOS(false);
723  setPriorities();
724  addSos();
725  OsiChooseStrong * chooser = new OsiChooseStrong(nonlinearSolver_);
726  branchingMethod_ = chooser;
727  chooser->setNumberStrong(intParam_[NumberStrong]);
728  chooser->setTrustStrongForSolution(false);
729  chooser->setNumberBeforeTrusted(intParam_[MinReliability]);
730  }
731  break;
732  default:
733  std::cout<<"Variable selection stragey not available with oa branch-and-cut."<<std::endl;
734  break;
735  }
736  }
737  /* Populate cut generation and heuristic procedures.*/
738  int ival;
739  options_->GetIntegerValue("nlp_solve_frequency",ival,prefix_.c_str());
740  if (ival != 0) {
741  CuttingMethod cg;
742  cg.frequency = ival;
743  OaNlpOptim * nlpsol = new OaNlpOptim(*this);
745  cg.cgl = nlpsol;
746  cg.id="NLP solution based oa cuts";
747  cutGenerators_.push_back(cg);
748  }
749 
750  options_->GetIntegerValue("filmint_ecp_cuts",ival, prefix_.c_str());
751  if (ival != 0) {
752  CuttingMethod cg;
753  cg.frequency = ival;
754  EcpCuts * ecp = new EcpCuts(*this);
756  cg.cgl = ecp;
757  cg.id = "Ecp cuts";
758  cutGenerators_.push_back(cg);
759  }
760 
761  if (algo == B_Hyb || algo == B_Ecp)
763 
764  int doFp;
765  options_->GetEnumValue("pump_for_minlp",doFp,prefix_.c_str());
766  if (doFp) {
767  CuttingMethod cg;
768  cg.frequency = -99;
769  MinlpFeasPump * oa = new MinlpFeasPump(*this);
771  cg.cgl = oa;
772  cg.id = "Feasibility Pump for MINLP.";
773  cutGenerators_.push_back(cg);
774 
775  }
776  int doOa;
777  options_->GetEnumValue("oa_decomposition",doOa,prefix_.c_str());
778  if (doOa) {
779  CuttingMethod cg;
780  cg.frequency = -99;
781  OACutGenerator2 * oa = new OACutGenerator2(*this);
783  cg.cgl = oa;
784  cg.id = "Outer Approximation decomposition.";
785  cutGenerators_.push_back(cg);
786 
787  }
788 
789  {
790  CuttingMethod cg;
791  cg.frequency = 1;
792  OaFeasibilityChecker * oa = new OaFeasibilityChecker(*this);
794  oa->setReassignLpSolver(false);
795  cg.cgl = oa;
796  cg.id = "Outer Approximation feasibility check.";
797  cg.atSolution = false;
798  cg.normal = true;
799  cg.always = true;
800  cutGenerators_.push_back(cg);
801  }
802 
803  {
804  CuttingMethod cg;
805  cg.frequency = 1;
806  OaFeasibilityChecker * oa = new OaFeasibilityChecker(*this);
808  oa->setReassignLpSolver(true);
809  cg.cgl = oa;
810  cg.id = "Outer Approximation strong branching solution check.";
811  cg.atSolution = true;
812  cg.normal = false;
813  cutGenerators_.push_back(cg);
814  }
815 
816  DummyHeuristic * oaHeu = new DummyHeuristic;
817  oaHeu->setNlp(nonlinearSolver_);
818  HeuristicMethod h;
819  h.heuristic = oaHeu;
820  h.id = "nonlinear programm";
821  heuristics_.push_back(h);
822 
823  Ipopt::Index doHeuristicRINS = false;
824  options()->GetEnumValue("heuristic_RINS",doHeuristicRINS,prefix_.c_str());
825  if(doHeuristicRINS){
826  HeuristicRINS* rins = new HeuristicRINS(this);
827  HeuristicMethod h;
828  h.heuristic = rins;
829  h.id = "RINS";
830  heuristics_.push_back(h);
831  }
832 
833  Ipopt::Index doHeuristicLocalBranching = false;
834  options()->GetEnumValue("heuristic_local_branching",doHeuristicLocalBranching,prefix_.c_str());
835  if(doHeuristicLocalBranching){
836  HeuristicLocalBranching* local_branching = new HeuristicLocalBranching(this);
837  HeuristicMethod h;
838  h.heuristic = local_branching;
839  h.id = "LocalBranching";
840  heuristics_.push_back(h);
841  }
842 
843  Ipopt::Index doHeuristicFPump = false;
844  options()->GetEnumValue("heuristic_feasibility_pump",doHeuristicFPump,prefix_.c_str());
845  if(doHeuristicFPump){
846  HeuristicFPump* feasibility_pump = new HeuristicFPump(this);
847  HeuristicMethod h;
848  h.heuristic = feasibility_pump;
849  h.id = "FPump";
850  heuristics_.push_back(h);
851  }
852 
853  Ipopt::Index doHeuristicDiveFractional = false;
854  options()->GetEnumValue("heuristic_dive_fractional",doHeuristicDiveFractional,prefix_.c_str());
855  if(doHeuristicDiveFractional){
856  HeuristicDiveFractional* dive_fractional = new HeuristicDiveFractional(this);
857  HeuristicMethod h;
858  h.heuristic = dive_fractional;
859  h.id = "DiveFractional";
860  heuristics_.push_back(h);
861  }
862 
863  Ipopt::Index doHeuristicDiveVectorLength = false;
864  options()->GetEnumValue("heuristic_dive_vectorLength",doHeuristicDiveVectorLength,prefix_.c_str());
865  if(doHeuristicDiveVectorLength){
866  HeuristicDiveVectorLength* dive_vectorLength = new HeuristicDiveVectorLength(this);
867  HeuristicMethod h;
868  h.heuristic = dive_vectorLength;
869  h.id = "DiveVectorLength";
870  heuristics_.push_back(h);
871  }
872 
873  Ipopt::Index doHeuristicDiveMIPFractional = false;
874  options()->GetEnumValue("heuristic_dive_MIP_fractional",doHeuristicDiveMIPFractional,prefix_.c_str());
875  if(doHeuristicDiveMIPFractional){
876  HeuristicDiveMIPFractional* dive_MIP_fractional = new HeuristicDiveMIPFractional(this);
877  HeuristicMethod h;
878  h.heuristic = dive_MIP_fractional;
879  h.id = "DiveMIPFractional";
880  heuristics_.push_back(h);
881  }
882 
883  Ipopt::Index doHeuristicDiveMIPVectorLength = false;
884  options()->GetEnumValue("heuristic_dive_MIP_vectorLength",doHeuristicDiveMIPVectorLength,prefix_.c_str());
885  if(doHeuristicDiveMIPVectorLength){
886  HeuristicDiveMIPVectorLength* dive_MIP_vectorLength = new HeuristicDiveMIPVectorLength(this);
887  HeuristicMethod h;
888  h.heuristic = dive_MIP_vectorLength;
889  h.id = "DiveMIPVectorLength";
890  heuristics_.push_back(h);
891  }
892 
893 #if 0
894  if(true){
895  InnerApproximation * inner = new InnerApproximation(this);
896  HeuristicMethod h;
897  h.heuristic = inner;
898  h.id = "InnerApproximation";
899  heuristics_.push_back(h);
900  }
901 #endif
902  setup_time += CoinCpuTime();
903  doubleParam_[MaxTime] -= setup_time;
904  }
905 
906 
908  {
909  if (algo_ != Dummy)
910  return algo_;
911  if (IsValid(options_)) {
912  int ival;
913  options_->GetEnumValue("algorithm", ival,prefix_.c_str());
914  return Algorithm(ival);
915  }
916  else return Algorithm(3);
917  }
918 
919 }/* end namespace Bonmin*/
920 
void setOnlyPseudoWhenTrusted(bool only_pseudo_when_trusted)
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register OaNlpOptim options.
int intParam_[NumberIntParam]
storage of integer parameters.
void getOuterApproximation(OsiCuts &cs, int getObj, const double *x2, bool global)
Get the outer approximation constraints at the current optimal point.
Type for heuristic method with its string identification.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register all the options for class instance.
Definition: BonCbcNode.cpp:71
CuttingMethods cutGenerators_
Cut generation methods.
This class chooses a variable to branch on.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register OA options.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
void passInMessageHandler(CoinMessageHandler *handler)
void use(const OsiTMINLPInterface &nlp)
use existing TMINLP interface (containing the options).
This class chooses a variable to branch on.
This is class provides an Osi interface for a Mixed Integer Linear Program expressed as a TMINLP (so ...
Spetial option in particular for Cbc.
HeuristicMethods heuristics_
Heuristic methods.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register ecp cuts options.
Definition: BonEcpCuts.cpp:146
bool IsValid(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:465
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register the options common to all local search based heuristics.
Algorithm
Type of algorithms which can be used.
Number of candidates for strong branching.
void passInMessageHandler(CoinMessageHandler *handler)
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register OA options.
void setPriorities()
Set the priorities into OsiTMINLPInterface when needed.
BonminSetup(const CoinMessageHandler *handler=NULL)
Default constructor.
OsiTMINLPInterface * nonlinearSolver_
Storage of the non-linear solver used.
Minimum reliability before trust pseudo-costs.
void ignoreFailures()
tell to ignore the failures (don&#39;t throw, don&#39;t fathom, don&#39;t report)
Class to perform OA in its classical form.
Type for cut generation method with its frequency and string identification.
Class to perform OA in its classical form.
OsiChooseVariable * branchingMethod_
Branching method.
void fint fint fint real fint real real real real real real real real real * e
A class to have all elements necessary to setup a branch-and-bound.
Bonmin::Algorithm getAlgorithm()
Get the algorithm used.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register the options common to all local search based heuristics.
static void registerAllOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register all bonmin type executable options.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register the options common to all local search based heuristics.
void initializeBHyb(bool createContinuousSolver=false)
Initialize a branch-and-cut with some OA.
Implementation of BonChooseVariable for curvature-based braching.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register OA options.
void initializeBBB()
Initialize a plain branch-and-bound.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register the options common to all local search based heuristics.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register the options for this heuristic.
void addSos()
Add SOS constraints to OsiTMINLPInterface when needed.
Ipopt::SmartPtr< TMINLP2OsiLP > linearizer_
Method to linearize MINLPs.
Ipopt::SmartPtr< Ipopt::OptionsList > options_
List of Options.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register the options common to all local search based heuristics.
Log level for root relaxation.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register the options common to all local search based heuristics.
void setNlp(OsiTMINLPInterface *si)
Set nlp_.
bool hasGeneralInteger()
Say if problem has general integer variables.
Definition: BonTMINLP.cpp:113
static void registerAllOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register all the options for this algorithm instance.
double doubleParam_[NumberDoubleParam]
storage of double parameters.
std::string prefix_
Prefix to use when reading options.
Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions_
Registered Options.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register the options common to all local search based heuristics.
static void registerMilpCutGenerators(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register standard MILP cut generators.
void gatherParametersValues()
Get the values of base parameters from the options stored.
Ipopt::SmartPtr< Ipopt::OptionsList > options()
Acces list of Options.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register the options common to all local search based heuristics.
static char prefix[100]
Definition: BM_lp.cpp:26
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register the options common to all local search based heuristics.
CoinMessageHandler * messageHandler_
separate message handler.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register the options common to all local search based heuristics.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register options for that Oa based cut generation method.
void passInMessageHandler(const CoinMessageHandler *handler)
Generate cuts for the nlp corresponding to continuous relaxation at a node.
virtual void registerOptions()
Register all the options for this algorithm instance.
virtual void extractLinearRelaxation(OsiSolverInterface &si, const double *x, bool getObj=1)
Extract a linear relaxation of the MINLP.
OsiSolverInterface * continuousSolver_
Storage of continuous solver.
const char * prefix() const
Get prefix to use for options.
Implementation of BonChooseVariable for curvature-based braching.
void addMilpCutGenerators()
Add milp cut generators according to options.
void initialize(Ipopt::SmartPtr< TMINLP > tminlp, bool createContinuousSolver=true)
Initialize, read options and create appropriate bonmin setup.