source: trunk/Bonmin/src/Algorithms/BonBonminSetup.cpp @ 2006

Last change on this file since 2006 was 2006, checked in by pbonami, 7 years ago

Don't change num_cut_passes in B-Ecp

File size: 33.4 KB
Line 
1// (C) Copyright International Business Machines Corporation 2007
2// All Rights Reserved.
3// This code is published under the Common 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
15#include "BonCurvBranchingSolver.hpp"
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"
48#include "BonLinearCutsGenerator.hpp"
49
50#include "BonFixAndSolveHeuristic.hpp"
51#include "BonDummyPump.hpp"
52#include "BonPumpForMinlp.hpp"
53#include "BonHeuristicRINS.hpp"
54#include "BonHeuristicLocalBranching.hpp"
55#include "BonHeuristicFPump.hpp"
56#include "BonHeuristicDiveFractional.hpp"
57#include "BonHeuristicDiveVectorLength.hpp"
58#include "BonHeuristicDiveMIPFractional.hpp"
59#include "BonHeuristicDiveMIPVectorLength.hpp"
60#include "BonMilpRounding.hpp"
61//#include "BonInnerApproximation.hpp"
62namespace Bonmin
63{
64  BonminSetup::BonminSetup(const CoinMessageHandler * handler):BabSetupBase(handler),algo_(Dummy)
65  {}
66
67  BonminSetup::BonminSetup(const BonminSetup &other):BabSetupBase(other),
68      algo_(other.algo_)
69  {}
70
71  BonminSetup::BonminSetup(const BonminSetup &other,
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
85      nonlinearSolver_->extractLinearRelaxation(*continuousSolver_);
86      // say bound dubious, does cuts at solution
87      OsiBabSolver * extraStuff = new OsiBabSolver(3);
88      continuousSolver_->setAuxiliaryInfo(extraStuff);
89      delete extraStuff;
90    }
91  }
92  BonminSetup::BonminSetup(const BonminSetup &other,
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  }
104  void BonminSetup::registerAllOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions)
105  {
106    BabSetupBase::registerAllOptions(roptions);
107
108    /* Outer Approximation options.*/
109    OACutGenerator2::registerOptions(roptions);
110    OaFeasibilityChecker::registerOptions(roptions);
111    MinlpFeasPump::registerOptions(roptions);
112    EcpCuts::registerOptions(roptions);
113    OaNlpOptim::registerOptions(roptions);
114    SubMipSolver::registerOptions(roptions);
115
116
117    BonCbcFullNodeInfo::registerOptions(roptions);
118
119
120    registerMilpCutGenerators(roptions);
121
122
123    /** Heursitics.*/
124    LocalSolverBasedHeuristic::registerOptions(roptions);
125    FixAndSolveHeuristic::registerOptions(roptions);
126    DummyPump::registerOptions(roptions);
127    MilpRounding::registerOptions(roptions);
128    PumpForMinlp::registerOptions(roptions);
129    HeuristicRINS::registerOptions(roptions);
130    HeuristicLocalBranching::registerOptions(roptions);
131    HeuristicFPump::registerOptions(roptions);
132    HeuristicDiveFractional::registerOptions(roptions);
133    HeuristicDiveVectorLength::registerOptions(roptions);
134    HeuristicDiveMIPFractional::registerOptions(roptions);
135    HeuristicDiveMIPVectorLength::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
154  /** Register all the Bonmin options.*/
155  void
156  BonminSetup::registerOptions()
157  {
158    registerAllOptions(roptions_);
159  }
160
161  /** Initialize, read options and create appropriate bonmin setup using initialized tminlp.*/
162  void
163  BonminSetup::initialize(Ipopt::SmartPtr<TMINLP> tminlp, bool createContinuousSolver /*= false*/)
164  {
165
166    use(tminlp);
167    BabSetupBase::gatherParametersValues(options_);
168    algo_ = getAlgorithm();
169    if (algo_ == B_BB)
170      initializeBBB();
171    else
172      initializeBHyb(createContinuousSolver);
173  }
174
175  /** Initialize, read options and create appropriate bonmin setup using initialized tminlp.*/
176  void
177  BonminSetup::initialize(const OsiTMINLPInterface &nlpSi, bool createContinuousSolver /*= false*/)
178  {
179    use(nlpSi);
180    BabSetupBase::gatherParametersValues(options_);
181    Algorithm algo = getAlgorithm();
182    if (algo == B_BB)
183      initializeBBB();
184    else
185      initializeBHyb(createContinuousSolver);
186  }
187
188  /** Register standard MILP cut generators. */
189  void
190  BonminSetup::registerMilpCutGenerators(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions)
191  {
192    roptions->SetRegisteringCategory("MILP cutting planes in hybrid", RegisteredOptions::BonminCategory);
193
194    roptions->AddLowerBoundedIntegerOption("Gomory_cuts",
195        "Frequency k (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
267  /** Add milp cut generators according to options.*/
268  void
269  BonminSetup::addMilpCutGenerators()
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
398  BonminSetup::initializeBBB()
399  {
400    continuousSolver_ = nonlinearSolver_;
401    nonlinearSolver_->ignoreFailures();
402    OsiBabSolver extraStuff(2);
403    continuousSolver_->setAuxiliaryInfo(&extraStuff);
404
405    intParam_[BabSetupBase::SpecialOption] = 16;
406    if (!options_->GetIntegerValue("number_before_trust",intParam_[BabSetupBase::MinReliability],prefix_.c_str())) {
407      intParam_[BabSetupBase::MinReliability] = 1;
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())) {
412      intParam_[BabSetupBase::NumberStrong] = 1000;
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;
462         case NLP_STRONG_BRANCHING:
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();
489      branchingMethod_ = new BonRandomChoice(nonlinearSolver_);
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);
630      nonlinearSolver_->forceSolverOutput(intParam_[RootLogLevel]); 
631
632      if(IsValid(linearizer_))//Use user provided linearizer
633        nonlinearSolver_->set_linearizer(linearizer_);
634
635      nonlinearSolver_->extractLinearRelaxation(*continuousSolver_);
636      nonlinearSolver_->setSolverOutputToDefault(); 
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);
744      nlpsol->passInMessageHandler(messageHandler_);
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);
755      ecp->passInMessageHandler(messageHandler_);
756      cg.cgl = ecp;
757      cg.id = "Ecp cuts";
758      cutGenerators_.push_back(cg);
759    }
760
761    if (algo == B_Hyb || algo == B_Ecp)
762      addMilpCutGenerators();
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);
770      oa->passInMessageHandler(messageHandler_);
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);
782      oa->passInMessageHandler(messageHandler_);
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);
793      oa->passInMessageHandler(messageHandler_);
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);
807      oa->passInMessageHandler(messageHandler_);
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
907  Algorithm BonminSetup::getAlgorithm()
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
Note: See TracBrowser for help on using the repository browser.