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

Last change on this file since 2003 was 2003, checked in by stefan, 7 years ago

fix typo in setting of num_cut_passes option if running ecp

File size: 33.5 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      o_name = prefix_ + "num_cut_passes";
700      options_->SetIntegerValue(o_name.c_str(), 1, true, true);
701    }
702//#define GREAT_STUFF_FOR_ANDREAS
703#ifdef GREAT_STUFF_FOR_ANDREAS
704    printf("ToDo: Clean me up in Bab::branchAndBound\n");
705    OsiCuts cuts;
706    nonlinearSolver_->getOuterApproximation(cuts, true, NULL, true);
707    continuousSolver_->applyCuts(cuts);
708#endif
709
710
711    int varSelection;
712    options_->GetEnumValue("variable_selection",varSelection,prefix_.c_str());
713    if (varSelection > RELIABILITY_BRANCHING) {
714      switch (varSelection){
715        case OSI_SIMPLE:
716          continuousSolver_->findIntegersAndSOS(false);
717          setPriorities();
718          addSos();
719          branchingMethod_ = new OsiChooseVariable(nonlinearSolver_);
720   
721          break;
722        case OSI_STRONG:
723          {
724          continuousSolver_->findIntegersAndSOS(false);
725          setPriorities();
726          addSos();
727          OsiChooseStrong * chooser = new OsiChooseStrong(nonlinearSolver_);
728          branchingMethod_ = chooser;
729          chooser->setNumberStrong(intParam_[NumberStrong]);
730          chooser->setTrustStrongForSolution(false);
731          chooser->setNumberBeforeTrusted(intParam_[MinReliability]);
732          }
733          break;
734        default:
735          std::cout<<"Variable selection stragey not available with oa branch-and-cut."<<std::endl;
736          break;
737     }
738    }
739    /* Populate cut generation and heuristic procedures.*/
740    int ival;
741    options_->GetIntegerValue("nlp_solve_frequency",ival,prefix_.c_str());
742    if (ival != 0) {
743      CuttingMethod cg;
744      cg.frequency = ival;
745      OaNlpOptim * nlpsol = new OaNlpOptim(*this);
746      nlpsol->passInMessageHandler(messageHandler_);
747      cg.cgl = nlpsol;
748      cg.id="NLP solution based oa cuts";
749      cutGenerators_.push_back(cg);
750    }
751
752    options_->GetIntegerValue("filmint_ecp_cuts",ival, prefix_.c_str());
753    if (ival != 0) {
754      CuttingMethod cg;
755      cg.frequency = ival;
756      EcpCuts * ecp = new EcpCuts(*this);
757      ecp->passInMessageHandler(messageHandler_);
758      cg.cgl = ecp;
759      cg.id = "Ecp cuts";
760      cutGenerators_.push_back(cg);
761    }
762
763    if (algo == B_Hyb || algo == B_Ecp)
764      addMilpCutGenerators();
765
766    int doFp;
767    options_->GetEnumValue("pump_for_minlp",doFp,prefix_.c_str());
768    if (doFp) {
769      CuttingMethod cg;
770      cg.frequency = -99;
771      MinlpFeasPump * oa = new MinlpFeasPump(*this);
772      oa->passInMessageHandler(messageHandler_);
773      cg.cgl = oa;
774      cg.id = "Feasibility Pump for MINLP.";
775      cutGenerators_.push_back(cg);
776
777    }
778    int doOa;
779    options_->GetEnumValue("oa_decomposition",doOa,prefix_.c_str());
780    if (doOa) {
781      CuttingMethod cg;
782      cg.frequency = -99;
783      OACutGenerator2 * oa = new OACutGenerator2(*this);
784      oa->passInMessageHandler(messageHandler_);
785      cg.cgl = oa;
786      cg.id = "Outer Approximation decomposition.";
787      cutGenerators_.push_back(cg);
788
789    }
790
791    {
792      CuttingMethod cg;
793      cg.frequency = 1;
794      OaFeasibilityChecker * oa = new OaFeasibilityChecker(*this);
795      oa->passInMessageHandler(messageHandler_);
796      oa->setReassignLpSolver(false);
797      cg.cgl = oa;
798      cg.id = "Outer Approximation feasibility check.";
799      cg.atSolution = false;
800      cg.normal = true;
801      cg.always = true;
802      cutGenerators_.push_back(cg);
803    }
804
805    {
806      CuttingMethod cg;
807      cg.frequency = 1;
808      OaFeasibilityChecker * oa = new OaFeasibilityChecker(*this);
809      oa->passInMessageHandler(messageHandler_);
810      oa->setReassignLpSolver(true);
811      cg.cgl = oa;
812      cg.id = "Outer Approximation strong branching solution check.";
813      cg.atSolution = true;
814      cg.normal = false;
815      cutGenerators_.push_back(cg);
816    }
817
818    DummyHeuristic * oaHeu = new DummyHeuristic;
819    oaHeu->setNlp(nonlinearSolver_);
820    HeuristicMethod h;
821    h.heuristic = oaHeu;
822    h.id = "nonlinear programm";
823    heuristics_.push_back(h);
824
825    Ipopt::Index doHeuristicRINS = false;
826    options()->GetEnumValue("heuristic_RINS",doHeuristicRINS,prefix_.c_str());
827    if(doHeuristicRINS){
828      HeuristicRINS* rins = new HeuristicRINS(this);
829      HeuristicMethod h;
830      h.heuristic = rins;
831      h.id = "RINS";
832      heuristics_.push_back(h);
833    }
834
835    Ipopt::Index doHeuristicLocalBranching = false;
836    options()->GetEnumValue("heuristic_local_branching",doHeuristicLocalBranching,prefix_.c_str());
837    if(doHeuristicLocalBranching){
838      HeuristicLocalBranching* local_branching = new HeuristicLocalBranching(this);
839      HeuristicMethod h;
840      h.heuristic = local_branching;
841      h.id = "LocalBranching";
842      heuristics_.push_back(h);
843    }
844
845    Ipopt::Index doHeuristicFPump = false;
846    options()->GetEnumValue("heuristic_feasibility_pump",doHeuristicFPump,prefix_.c_str());
847    if(doHeuristicFPump){
848      HeuristicFPump* feasibility_pump = new HeuristicFPump(this);
849      HeuristicMethod h;
850      h.heuristic = feasibility_pump;
851      h.id = "FPump";
852      heuristics_.push_back(h);
853    }
854
855    Ipopt::Index doHeuristicDiveFractional = false;
856    options()->GetEnumValue("heuristic_dive_fractional",doHeuristicDiveFractional,prefix_.c_str());
857    if(doHeuristicDiveFractional){
858      HeuristicDiveFractional* dive_fractional = new HeuristicDiveFractional(this);
859      HeuristicMethod h;
860      h.heuristic = dive_fractional;
861      h.id = "DiveFractional";
862      heuristics_.push_back(h);
863    }
864
865    Ipopt::Index doHeuristicDiveVectorLength = false;
866    options()->GetEnumValue("heuristic_dive_vectorLength",doHeuristicDiveVectorLength,prefix_.c_str());
867    if(doHeuristicDiveVectorLength){
868      HeuristicDiveVectorLength* dive_vectorLength = new HeuristicDiveVectorLength(this);
869      HeuristicMethod h;
870      h.heuristic = dive_vectorLength;
871      h.id = "DiveVectorLength";
872      heuristics_.push_back(h);
873    }
874
875    Ipopt::Index doHeuristicDiveMIPFractional = false;
876    options()->GetEnumValue("heuristic_dive_MIP_fractional",doHeuristicDiveMIPFractional,prefix_.c_str());
877    if(doHeuristicDiveMIPFractional){
878      HeuristicDiveMIPFractional* dive_MIP_fractional = new HeuristicDiveMIPFractional(this);
879      HeuristicMethod h;
880      h.heuristic = dive_MIP_fractional;
881      h.id = "DiveMIPFractional";
882      heuristics_.push_back(h);
883    }
884
885    Ipopt::Index doHeuristicDiveMIPVectorLength = false;
886    options()->GetEnumValue("heuristic_dive_MIP_vectorLength",doHeuristicDiveMIPVectorLength,prefix_.c_str());
887    if(doHeuristicDiveMIPVectorLength){
888      HeuristicDiveMIPVectorLength* dive_MIP_vectorLength = new HeuristicDiveMIPVectorLength(this);
889      HeuristicMethod h;
890      h.heuristic = dive_MIP_vectorLength;
891      h.id = "DiveMIPVectorLength";
892      heuristics_.push_back(h);
893    }
894
895#if 0
896    if(true){
897      InnerApproximation * inner = new InnerApproximation(this);
898      HeuristicMethod h;
899      h.heuristic = inner;
900      h.id = "InnerApproximation";
901      heuristics_.push_back(h);
902    }
903#endif
904    setup_time += CoinCpuTime();
905    doubleParam_[MaxTime] -= setup_time;
906  }
907
908
909  Algorithm BonminSetup::getAlgorithm()
910  {
911    if (algo_ != Dummy)
912      return algo_;
913    if (IsValid(options_)) {
914      int ival;
915      options_->GetEnumValue("algorithm", ival,prefix_.c_str());
916      return Algorithm(ival);
917    }
918    else return Algorithm(3);
919  }
920
921}/* end namespace Bonmin*/
922
Note: See TracBrowser for help on using the repository browser.