/home/coin/SVN-release/OS-2.4.2/Bonmin/src/Algorithms/BonBonminSetup.cpp

Go to the documentation of this file.
00001 // (C) Copyright International Business Machines Corporation 2007
00002 // All Rights Reserved.
00003 // This code is published under the Common Public License.
00004 //
00005 // Authors :
00006 // Pierre Bonami, International Business Machines Corporation
00007 //
00008 // Date : 04/13/2007
00009 
00010 #include "BonminConfig.h"
00011 #include "OsiClpSolverInterface.hpp"
00012 
00013 #include "BonBonminSetup.hpp"
00014 #ifdef BONMIN_CURVATURE_BRANCHING
00015 #include "BonCurvBranchingSolver.hpp"
00016 #endif
00017 #include "BonChooseVariable.hpp"
00018 #include "BonRandomChoice.hpp"
00019 #include "BonDiver.hpp"
00020 #include "BonQpBranchingSolver.hpp"
00021 #include "BonLpBranchingSolver.hpp"
00022 
00023 //OA machinery
00024 #include "BonDummyHeuristic.hpp"
00025 #include "BonOACutGenerator2.hpp"
00026 #include "BonFpForMinlp.hpp"
00027 #include "BonOaFeasChecker.hpp"
00028 #include "BonOaNlpOptim.hpp"
00029 #include "BonEcpCuts.hpp"
00030 
00031 #include "BonCbcNode.hpp"
00032 #ifdef COIN_HAS_FILTERSQP
00033 # include "BonFilterSolver.hpp"
00034 #endif
00035 
00036 //MILP cuts
00037 #include "CglGomory.hpp"
00038 #include "CglProbing.hpp"
00039 #include "CglKnapsackCover.hpp"
00040 #include "CglOddHole.hpp"
00041 #include "CglClique.hpp"
00042 #include "CglFlowCover.hpp"
00043 #include "CglMixedIntegerRounding2.hpp"
00044 #include "CglTwomir.hpp"
00045 #include "CglPreProcess.hpp"
00046 #include "CglLandP.hpp"
00047 #include "CglRedSplit.hpp"
00048 #include "BonLinearCutsGenerator.hpp"
00049 
00050 #include "BonFixAndSolveHeuristic.hpp"
00051 #include "BonDummyPump.hpp"
00052 #include "BonPumpForMinlp.hpp"
00053 #include "BonHeuristicRINS.hpp"
00054 #include "BonHeuristicLocalBranching.hpp"
00055 #include "BonHeuristicFPump.hpp"
00056 #include "BonHeuristicDiveFractional.hpp"
00057 #include "BonHeuristicDiveVectorLength.hpp"
00058 #include "BonHeuristicDiveMIPFractional.hpp"
00059 #include "BonHeuristicDiveMIPVectorLength.hpp"
00060 #include "BonMilpRounding.hpp"
00061 //#include "BonInnerApproximation.hpp"
00062 namespace Bonmin
00063 {
00064   BonminSetup::BonminSetup(const CoinMessageHandler * handler):BabSetupBase(handler),algo_(Dummy)
00065   {}
00066 
00067   BonminSetup::BonminSetup(const BonminSetup &other):BabSetupBase(other),
00068       algo_(other.algo_)
00069   {}
00070 
00071   BonminSetup::BonminSetup(const BonminSetup &other,
00072                            OsiTMINLPInterface &nlp):
00073       BabSetupBase(other, nlp),
00074       algo_(other.algo_)
00075   {
00076     if(algo_ != B_BB){
00077       assert(continuousSolver_ == NULL);
00078       continuousSolver_ = new OsiClpSolverInterface;
00079       int lpLogLevel;
00080       options_->GetIntegerValue("lp_log_level",lpLogLevel,prefix_.c_str());
00081       if(messageHandler_)
00082         continuousSolver_->passInMessageHandler(messageHandler_);
00083       continuousSolver_->messageHandler()->setLogLevel(lpLogLevel);
00084 
00085       nonlinearSolver_->extractLinearRelaxation(*continuousSolver_);
00086       // say bound dubious, does cuts at solution
00087       OsiBabSolver * extraStuff = new OsiBabSolver(3);
00088       continuousSolver_->setAuxiliaryInfo(extraStuff);
00089       delete extraStuff;
00090     }
00091   }
00092   BonminSetup::BonminSetup(const BonminSetup &other,
00093                            OsiTMINLPInterface &nlp,
00094                            const std::string &prefix):
00095     BabSetupBase(other, nlp, prefix),
00096     algo_(Dummy)
00097   {
00098    algo_ = getAlgorithm();
00099     if (algo_ == B_BB)
00100       initializeBBB();
00101     else
00102       initializeBHyb(true);
00103   }
00104   void BonminSetup::registerAllOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions)
00105   {
00106     BabSetupBase::registerAllOptions(roptions);
00107 
00108     /* Outer Approximation options.*/
00109     OACutGenerator2::registerOptions(roptions);
00110     OaFeasibilityChecker::registerOptions(roptions);
00111     MinlpFeasPump::registerOptions(roptions);
00112     EcpCuts::registerOptions(roptions);
00113     OaNlpOptim::registerOptions(roptions);
00114     SubMipSolver::registerOptions(roptions);
00115 
00116 
00117     BonCbcFullNodeInfo::registerOptions(roptions);
00118 
00119 
00120     registerMilpCutGenerators(roptions);
00121 
00122 
00124     LocalSolverBasedHeuristic::registerOptions(roptions);
00125     FixAndSolveHeuristic::registerOptions(roptions);
00126     DummyPump::registerOptions(roptions);
00127     MilpRounding::registerOptions(roptions);
00128     PumpForMinlp::registerOptions(roptions);
00129     HeuristicRINS::registerOptions(roptions);
00130     HeuristicLocalBranching::registerOptions(roptions);
00131     HeuristicFPump::registerOptions(roptions);
00132     HeuristicDiveFractional::registerOptions(roptions);
00133     HeuristicDiveVectorLength::registerOptions(roptions);
00134     HeuristicDiveMIPFractional::registerOptions(roptions);
00135     HeuristicDiveMIPVectorLength::registerOptions(roptions);
00136 
00137     roptions->SetRegisteringCategory("Algorithm choice", RegisteredOptions::BonminCategory);
00138     roptions->AddStringOption6("algorithm",
00139         "Choice of the algorithm.",
00140         "B-BB",
00141         "B-BB","simple branch-and-bound algorithm,",
00142         "B-OA","OA Decomposition algorithm,",
00143         "B-QG","Quesada and Grossmann branch-and-cut algorithm,",
00144         "B-Hyb","hybrid outer approximation based branch-and-cut,",
00145         "B-Ecp","ecp cuts based branch-and-cut a la FilMINT.",
00146         "B-iFP","Iterated Feasibility Pump for MINLP.",
00147         "This will preset some of the options of bonmin depending on the algorithm choice."
00148                               );
00149     roptions->setOptionExtraInfo("algorithm",127);
00150 
00151 
00152   }
00153 
00155   void
00156   BonminSetup::registerOptions()
00157   {
00158     registerAllOptions(roptions_);
00159   }
00160 
00162   void
00163   BonminSetup::initialize(Ipopt::SmartPtr<TMINLP> tminlp, bool createContinuousSolver /*= false*/)
00164   {
00165 
00166     use(tminlp);
00167     BabSetupBase::gatherParametersValues(options_);
00168     algo_ = getAlgorithm();
00169     if (algo_ == B_BB)
00170       initializeBBB();
00171     else
00172       initializeBHyb(createContinuousSolver);
00173   }
00174 
00176   void
00177   BonminSetup::initialize(const OsiTMINLPInterface &nlpSi, bool createContinuousSolver /*= false*/)
00178   {
00179     use(nlpSi);
00180     BabSetupBase::gatherParametersValues(options_);
00181     Algorithm algo = getAlgorithm();
00182     if (algo == B_BB)
00183       initializeBBB();
00184     else
00185       initializeBHyb(createContinuousSolver);
00186   }
00187 
00189   void
00190   BonminSetup::registerMilpCutGenerators(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions)
00191   {
00192     roptions->SetRegisteringCategory("MILP cutting planes in hybrid", RegisteredOptions::BonminCategory);
00193 
00194     roptions->AddLowerBoundedIntegerOption("Gomory_cuts",
00195         "Frequency k (in terms of nodes) for generating Gomory cuts in branch-and-cut.",
00196         -100,-5,
00197         "If $k > 0$, cuts are generated every k nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
00198         "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
00199         "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
00200     roptions->setOptionExtraInfo("Gomory_cuts",119);
00201 #if 0
00202     roptions->AddBoundedIntegerOption("probing_cuts",
00203         "Frequency (in terms of nodes) for generating probing cuts in branch-and-cut",
00204         0,0,0,
00205         "If k > 0, cuts are generated every k nodes, if -99 < k < 0 cuts are generated every -k nodes but "
00206         "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
00207         "if k=-99 generate cuts only at the root node, if k=0 or 100 do not generate cuts.");
00208     roptions->setOptionExtraInfo("probing_cuts",0);
00209 #endif
00210     roptions->AddLowerBoundedIntegerOption("cover_cuts",
00211         "Frequency (in terms of nodes) for generating cover cuts in branch-and-cut",
00212         -100,0,
00213         "If $k > 0$, cuts are generated every k nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
00214         "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
00215         "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
00216     roptions->setOptionExtraInfo("cover_cuts",119);
00217 
00218     roptions->AddLowerBoundedIntegerOption("mir_cuts",
00219         "Frequency (in terms of nodes) for generating MIR cuts in branch-and-cut",
00220         -100,-5,
00221         "If $k > 0$, cuts are generated every k nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
00222         "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
00223         "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
00224     roptions->setOptionExtraInfo("mir_cuts",119);
00225     roptions->AddLowerBoundedIntegerOption("2mir_cuts",
00226         "Frequency (in terms of nodes) for generating 2-MIR cuts in branch-and-cut",
00227         -100,0,
00228         "If $k > 0$, cuts are generated every k nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
00229         "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
00230         "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
00231     roptions->setOptionExtraInfo("2mir_cuts",119);
00232 
00233     roptions->AddLowerBoundedIntegerOption("flow_cover_cuts",
00234         "Frequency (in terms of nodes) for generating flow cover cuts in branch-and-cut",
00235         -100,-5,
00236         "If $k > 0$, cuts are generated every k nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
00237         "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
00238         "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
00239     roptions->setOptionExtraInfo("flow_cover_cuts",119);
00240     roptions->AddLowerBoundedIntegerOption("lift_and_project_cuts",
00241         "Frequency (in terms of nodes) for generating lift-and-project cuts in branch-and-cut",
00242         -100,0,
00243         "If $k > 0$, cuts are generated every k nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
00244         "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
00245         "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
00246     roptions->setOptionExtraInfo("lift_and_project_cuts", 119);
00247     roptions->AddLowerBoundedIntegerOption("reduce_and_split_cuts",
00248         "Frequency (in terms of nodes) for generating reduce-and-split cuts in branch-and-cut",
00249         -100,0,
00250         "If $k > 0$, cuts are generated every k nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
00251         "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
00252         "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
00253     roptions->setOptionExtraInfo("reduce_and_split_cuts", 119);
00254 
00255 
00256     roptions->AddLowerBoundedIntegerOption("clique_cuts",
00257         "Frequency (in terms of nodes) for generating clique cuts in branch-and-cut",
00258         -100,-5,
00259         "If $k > 0$, cuts are generated every k nodes, if $-99 < k < 0$ cuts are generated every $-k$ nodes but "
00260         "Cbc may decide to stop generating cuts, if not enough are generated at the root node, "
00261         "if $k=-99$ generate cuts only at the root node, if $k=0$ or $100$ do not generate cuts.");
00262     roptions->setOptionExtraInfo("clique_cuts", 119);
00263 
00264   }
00265 
00266 
00268   void
00269   BonminSetup::addMilpCutGenerators()
00270   {
00271 
00272     int freq;
00273 
00274     options_->GetIntegerValue("Gomory_cuts", freq,prefix_.c_str());
00275 
00276     if (freq) {
00277       CuttingMethod cg;
00278       cg.frequency = freq;
00279       CglGomory * gom = new CglGomory;
00280       cg.cgl = gom;
00281       gom->setLimitAtRoot(5000);
00282       gom->setLimit(500);
00283       gom->setLargestFactorMultiplier(1e-08);
00284       cg.id = "Mixed Integer Gomory";
00285       cutGenerators_.push_back(cg);
00286     }
00287 
00288 #if 0
00289     options_->GetIntegerValue("probing_cuts",freq,prefix_.c_str());
00290     if (freq) {
00291       CuttingMethod cg;
00292       cg.frequency = freq;
00293       CglProbing * probe = new CglProbing;
00294       cg.cgl = probe;
00295       probe->setUsingObjective(1);
00296       probe->setMaxPass(3);
00297       probe->setMaxPassRoot(3);
00298       // Number of unsatisfied variables to look at
00299       probe->setMaxProbe(10);
00300       probe->setMaxProbeRoot(50);
00301       // How far to follow the consequences
00302       probe->setMaxLook(10);
00303       probe->setMaxLookRoot(50);
00304       probe->setMaxLookRoot(10);
00305       // Only look at rows with fewer than this number of elements
00306       probe->setMaxElements(200);
00307       probe->setRowCuts(3);
00308       cg.id = "Probing";
00309       cutGenerators_.push_back(cg);
00310     }
00311 #endif
00312 
00313     options_->GetIntegerValue("mir_cuts",freq,prefix_.c_str());
00314 
00315     if (freq) {
00316       CuttingMethod cg;
00317       cg.frequency = freq;
00318       CglMixedIntegerRounding2 * mir = new CglMixedIntegerRounding2;
00319       //CglMixedIntegerRounding2 * mir = new CglMixedIntegerRounding2(1, true, 1);
00320       cg.cgl = mir;
00321       cg.id = "Mixed Integer Rounding";
00322       cutGenerators_.push_back(cg);
00323     }
00324 
00325     options_->GetIntegerValue("2mir_cuts",freq,prefix_.c_str());
00326 
00327     if (freq) {
00328       CuttingMethod cg;
00329       cg.frequency = freq;
00330       CglTwomir * mir2 = new CglTwomir;
00331       cg.cgl = mir2;
00332       cg.id = "2-MIR";
00333       cutGenerators_.push_back(cg);
00334     }
00335 
00336     options_->GetIntegerValue("cover_cuts",freq,prefix_.c_str());
00337 
00338     if (freq) {
00339       CuttingMethod cg;
00340       cg.frequency = freq;
00341       CglKnapsackCover * cover = new CglKnapsackCover;
00342       cg.cgl = cover;
00343       cg.id = "Cover";
00344       cutGenerators_.push_back(cg);
00345     }
00346 
00347     options_->GetIntegerValue("clique_cuts",freq,prefix_.c_str());
00348 
00349     if (freq) {
00350       CuttingMethod cg;
00351       cg.frequency = freq;
00352       CglClique * clique = new CglClique;
00353       clique->setStarCliqueReport(false);
00354       clique->setRowCliqueReport(false);
00355       clique->setMinViolation(0.1);
00356 
00357       cg.cgl = clique;
00358       cg.id = "Clique";
00359       cutGenerators_.push_back(cg);
00360     }
00361 
00362     options_->GetIntegerValue("flow_cover_cuts",freq,prefix_.c_str());
00363 
00364     if (freq) {
00365       CuttingMethod cg;
00366       cg.frequency = freq;
00367       CglFlowCover * flow = new CglFlowCover;
00368       cg.cgl = flow;
00369       cg.id = "Flow Covers";
00370       cutGenerators_.push_back(cg);
00371     }
00372 
00373     options_->GetIntegerValue("lift_and_project_cuts",freq,prefix_.c_str());
00374 
00375     if (freq) {
00376       CuttingMethod cg;
00377       cg.frequency = freq;
00378       CglLandP * landp = new CglLandP;
00379       cg.cgl = landp;
00380       cg.id = "Lift-and-Project";
00381       cutGenerators_.push_back(cg);
00382     }
00383 
00384     options_->GetIntegerValue("reduce_and_split_cuts",freq,prefix_.c_str());
00385 
00386     if (freq) {
00387       CuttingMethod cg;
00388       cg.frequency = freq;
00389       CglRedSplit * rands = new CglRedSplit;
00390       cg.cgl = rands;
00391       cg.id = "Reduce-and-Split";
00392       cutGenerators_.push_back(cg);
00393     }
00394   }
00395 
00396 
00397   void
00398   BonminSetup::initializeBBB()
00399   {
00400     continuousSolver_ = nonlinearSolver_;
00401     nonlinearSolver_->ignoreFailures();
00402     OsiBabSolver extraStuff(2);
00403     continuousSolver_->setAuxiliaryInfo(&extraStuff);
00404 
00405     intParam_[BabSetupBase::SpecialOption] = 16;
00406     if (!options_->GetIntegerValue("number_before_trust",intParam_[BabSetupBase::MinReliability],prefix_.c_str())) {
00407       intParam_[BabSetupBase::MinReliability] = 1;
00408       std::string o_name = prefix_ + "number_before_trust";
00409       options_->SetIntegerValue(o_name.c_str(),intParam_[BabSetupBase::MinReliability],true,true);
00410     }
00411     if (!options_->GetIntegerValue("number_strong_branch",intParam_[BabSetupBase::NumberStrong],prefix_.c_str())) {
00412       intParam_[BabSetupBase::NumberStrong] = 1000;
00413       std::string o_name = prefix_ + "number_strong_branch";
00414       options_->SetIntegerValue(o_name.c_str(),intParam_[BabSetupBase::NumberStrong],true,true);
00415     }
00416     int varSelection;
00417     bool val = options_->GetEnumValue("variable_selection",varSelection,prefix_.c_str());
00418     if (!val){// || varSelection == STRONG_BRANCHING || varSelection == RELIABILITY_BRANCHING ) {
00419       std::string o_name = prefix_ + "variable_selection";
00420       options_->SetStringValue(o_name.c_str(), "nlp-strong-branching",true,true);
00421       varSelection = NLP_STRONG_BRANCHING;
00422     }
00423 
00424     switch (varSelection) {
00425 #ifdef BONMIN_CURVATURE_BRANCHING
00426     case CURVATURE_ESTIMATOR:
00427 #endif
00428     case QP_STRONG_BRANCHING:
00429     case LP_STRONG_BRANCHING:
00430     case NLP_STRONG_BRANCHING: {
00431         continuousSolver_->findIntegersAndSOS(false);
00432         setPriorities();
00433         addSos();
00434         Ipopt::SmartPtr<StrongBranchingSolver> strong_solver = NULL;
00435         BonChooseVariable * chooseVariable = new BonChooseVariable(*this, nonlinearSolver_);
00436         chooseVariable->passInMessageHandler(nonlinearSolver_->messageHandler());
00437         switch (varSelection) {
00438 #ifdef BONMIN_CURVATURE_BRANCHING
00439         case CURVATURE_ESTIMATOR:
00440           strong_solver = new CurvBranchingSolver(nonlinearSolver_);
00441           chooseVariable->setTrustStrongForSolution(false);
00442           chooseVariable->setTrustStrongForBound(false);
00443           //chooseVariable->setOnlyPseudoWhenTrusted(true);
00444           chooseVariable->setOnlyPseudoWhenTrusted(false);
00445           break;
00446 #endif
00447         case QP_STRONG_BRANCHING:
00448           chooseVariable->setTrustStrongForSolution(false);
00449           strong_solver = new QpBranchingSolver(nonlinearSolver_);
00450           // The bound returned from the QP can be wrong, since the
00451           // objective is not guaranteed to be an underestimator:
00452           chooseVariable->setTrustStrongForBound(false);
00453           //chooseVariable->setOnlyPseudoWhenTrusted(true);
00454           chooseVariable->setOnlyPseudoWhenTrusted(false);
00455           break;
00456         case LP_STRONG_BRANCHING:
00457           chooseVariable->setTrustStrongForSolution(false);
00458           strong_solver = new LpBranchingSolver(this);
00459           //chooseVariable->setOnlyPseudoWhenTrusted(true);
00460           chooseVariable->setOnlyPseudoWhenTrusted(false);
00461           break;
00462          case NLP_STRONG_BRANCHING:
00463           chooseVariable->setTrustStrongForSolution(false);
00464           chooseVariable->setTrustStrongForBound(true);
00465           chooseVariable->setOnlyPseudoWhenTrusted(false);
00466           break;
00467         }
00468         nonlinearSolver_->SetStrongBrachingSolver(strong_solver);
00469         branchingMethod_ = chooseVariable;
00470       }
00471       break;
00472     case OSI_SIMPLE:
00473       continuousSolver_->findIntegersAndSOS(false);
00474       setPriorities();
00475       addSos();
00476       branchingMethod_ = new OsiChooseVariable(nonlinearSolver_);
00477 
00478       break;
00479     case OSI_STRONG:
00480       continuousSolver_->findIntegersAndSOS(false);
00481       setPriorities();
00482       addSos();
00483       branchingMethod_ = new OsiChooseStrong(nonlinearSolver_);
00484       break;
00485     case RANDOM:
00486       continuousSolver_->findIntegersAndSOS(false);
00487       setPriorities();
00488       addSos();
00489       branchingMethod_ = new BonRandomChoice(nonlinearSolver_);
00490       break;
00491       //default:
00492       //abort();
00493     }
00494     if (branchingMethod_ != NULL) {
00495       branchingMethod_->setNumberStrong(intParam_[NumberStrong]);
00496     }
00497 
00498 
00499     Ipopt::Index doHeuristicDiveFractional = false;
00500     options()->GetEnumValue("heuristic_dive_fractional",doHeuristicDiveFractional,prefix_.c_str());
00501     if(doHeuristicDiveFractional){
00502       HeuristicDiveFractional* dive_fractional = new HeuristicDiveFractional(this);
00503       HeuristicMethod h;
00504       h.heuristic = dive_fractional;
00505       h.id = "DiveFractional";
00506       heuristics_.push_back(h);
00507     }
00508 
00509     Ipopt::Index doHeuristicDiveVectorLength = false;
00510     options()->GetEnumValue("heuristic_dive_vectorLength",doHeuristicDiveVectorLength,prefix_.c_str());
00511     if(doHeuristicDiveVectorLength){
00512       HeuristicDiveVectorLength* dive_vectorLength = new HeuristicDiveVectorLength(this);
00513       HeuristicMethod h;
00514       h.heuristic = dive_vectorLength;
00515       h.id = "DiveVectorLength";
00516       heuristics_.push_back(h);
00517     }
00518 
00519     Ipopt::Index doHeuristicDiveMIPFractional = false;
00520     if(!options()->GetEnumValue("heuristic_dive_MIP_fractional",doHeuristicDiveMIPFractional,prefix_.c_str())){
00521       doHeuristicDiveMIPFractional = true;
00522       std::string o_name = prefix_ + "heuristic_dive_MIP_fractional";
00523       options_->SetStringValue(o_name.c_str(), "yes",true,true);
00524     }
00525     if(doHeuristicDiveMIPFractional){
00526       HeuristicDiveMIPFractional* dive_MIP_fractional = new HeuristicDiveMIPFractional(this);
00527       HeuristicMethod h;
00528       h.heuristic = dive_MIP_fractional;
00529       h.id = "DiveMIPFractional";
00530       heuristics_.push_back(h);
00531     }
00532 
00533     Ipopt::Index doHeuristicDiveMIPVectorLength = false;
00534     options()->GetEnumValue("heuristic_dive_MIP_vectorLength",doHeuristicDiveMIPVectorLength,prefix_.c_str());
00535     if(doHeuristicDiveMIPVectorLength){
00536       HeuristicDiveMIPVectorLength* dive_MIP_vectorLength = new HeuristicDiveMIPVectorLength(this);
00537       HeuristicMethod h;
00538       h.heuristic = dive_MIP_vectorLength;
00539       h.id = "DiveMIPVectorLength";
00540       heuristics_.push_back(h);
00541     }
00542     Ipopt::Index doHeuristicFPump = false;
00543     if(!nonlinearSolver_->model()->hasGeneralInteger() && !options()->GetEnumValue("heuristic_feasibility_pump",doHeuristicFPump,prefix_.c_str())){
00544       doHeuristicFPump = true;
00545       std::string o_name = prefix_ + "heuristic_feasibility_pump";
00546       options_->SetStringValue(o_name.c_str(), "yes",true,true);
00547     }
00548     if(doHeuristicFPump){
00549       HeuristicFPump* feasibility_pump = new HeuristicFPump(this);
00550       HeuristicMethod h;
00551       h.heuristic = feasibility_pump;
00552       h.id = "FPump";
00553       heuristics_.push_back(h);
00554     }
00555 
00556     Ipopt::Index doFixAndSolve = false;
00557     options()->GetEnumValue("fix_and_solve_heuristic",doFixAndSolve,prefix_.c_str());
00558     if(doFixAndSolve){
00559       FixAndSolveHeuristic* fix_and_solve = new FixAndSolveHeuristic(this);
00560       HeuristicMethod h;
00561       h.heuristic = fix_and_solve;
00562       h.id = "Fix and Solve";
00563       heuristics_.push_back(h);
00564     }
00565 
00566     Ipopt::Index doDummyPump = false;
00567     options()->GetEnumValue("dummy_pump_heuristic",doDummyPump,prefix_.c_str());
00568     if(doDummyPump){
00569       DummyPump* fix_and_solve = new DummyPump(this);
00570       HeuristicMethod h;
00571       h.heuristic = fix_and_solve;
00572       h.id = "Dummy pump";
00573       heuristics_.push_back(h);
00574     }
00575 
00576     Ipopt::Index doHeuristicRINS = false;
00577     options()->GetEnumValue("heuristic_RINS",doHeuristicRINS,prefix_.c_str());
00578     if(doHeuristicRINS){
00579       HeuristicRINS* rins = new HeuristicRINS(this);
00580       HeuristicMethod h;
00581       h.heuristic = rins;
00582       h.id = "RINS";
00583       heuristics_.push_back(h);
00584     }
00585 
00586     Ipopt::Index doHeuristicLocalBranching = false;
00587     options()->GetEnumValue("heuristic_local_branching",doHeuristicLocalBranching,prefix_.c_str());
00588     if(doHeuristicLocalBranching){
00589       HeuristicLocalBranching* local_branching = new HeuristicLocalBranching(this);
00590       HeuristicMethod h;
00591       h.heuristic = local_branching;
00592       h.id = "LocalBranching";
00593       heuristics_.push_back(h);
00594     }
00595 
00596     Ipopt::Index doHeuristicPumpForMinlp = false;
00597     options()->GetEnumValue("pump_for_minlp",doHeuristicPumpForMinlp,prefix_.c_str());
00598     if(doHeuristicPumpForMinlp){
00599       PumpForMinlp * pump = new PumpForMinlp(this);
00600       HeuristicMethod h;
00601       h.heuristic = pump;
00602       h.id = "Pump for MINLP";
00603       heuristics_.push_back(h);
00604     }
00605 
00606     Ipopt::Index doHeuristicMilpRounding = false;
00607     options()->GetEnumValue("MILP_rounding_heuristic",doHeuristicMilpRounding,prefix_.c_str());
00608     if(doHeuristicMilpRounding){
00609       MilpRounding * round = new MilpRounding(this);
00610       HeuristicMethod h;
00611       h.heuristic = round;
00612       h.id = "MILP Rounding";
00613       heuristics_.push_back(h);
00614     }
00615   }
00616 
00617 
00618   void
00619   BonminSetup::initializeBHyb(bool createContinuousSolver /*= false*/)
00620   {
00621     double setup_time = -CoinCpuTime();
00622     if (createContinuousSolver) {
00623       /* Create linear solver */
00624       continuousSolver_ = new OsiClpSolverInterface;
00625       int lpLogLevel;
00626       options_->GetIntegerValue("lp_log_level",lpLogLevel,prefix_.c_str());
00627       if(messageHandler_)
00628         continuousSolver_->passInMessageHandler(messageHandler_);
00629       continuousSolver_->messageHandler()->setLogLevel(lpLogLevel);
00630       nonlinearSolver_->forceSolverOutput(intParam_[RootLogLevel]); 
00631       nonlinearSolver_->extractLinearRelaxation(*continuousSolver_);
00632       nonlinearSolver_->setSolverOutputToDefault(); 
00633       // say bound dubious, does cuts at solution
00634       OsiBabSolver * extraStuff = new OsiBabSolver(3);
00635       continuousSolver_->setAuxiliaryInfo(extraStuff);
00636       delete extraStuff;
00637     }
00638     Algorithm algo = getAlgorithm();
00639     std::string prefix = (prefix_ == "bonmin.") ? "" : prefix_;
00640     if (algo == B_Hyb) {
00641       std::string o_name = prefix_ + "oa_decomposition";
00642       options_->SetStringValue(o_name.c_str(),"no", true, true);
00643       o_name = prefix_ + "pump_for_minlp";
00644       options_->SetStringValue(o_name.c_str(),"yes", true, true);
00645       o_name = prefix + "pump_for_minlp.time_limit";
00646       options_->SetNumericValue(o_name.c_str(),30, true, true);
00647       o_name = prefix + "pump_for_minlp.solution_limit";
00648       options_->SetIntegerValue(o_name.c_str(),3, true, true);
00649     }
00650     else if (algo == B_OA) {
00651       std::string o_name = prefix_ + "oa_decomposition";
00652       options_->SetStringValue(o_name.c_str(),"yes", true, true);
00653       o_name = prefix + "oa_decomposition.time_limit";
00654       options_->SetNumericValue(o_name.c_str(),DBL_MAX, true, true);
00655       o_name = prefix_ + "pump_for_minlp";
00656       options_->SetStringValue(o_name.c_str(),"no", true, true);
00657       o_name = prefix + "nlp_solve_frequency";
00658       options_->SetIntegerValue(o_name.c_str(), 0, true, true);
00659       o_name = prefix + "bb_log_level";
00660       options_->SetIntegerValue(o_name.c_str(), 0, true, true);
00661     }
00662     else if (algo == B_IFP) {
00663       std::string o_name = prefix_ + "oa_decomposition";
00664       options_->SetStringValue(o_name.c_str(),"no", true, true);
00665       o_name = prefix_ + "pump_for_minlp";
00666       options_->SetStringValue(o_name.c_str(),"yes", true, true);
00667       o_name = prefix + "pump_for_minlp.time_limit";
00668       options_->SetNumericValue(o_name.c_str(),DBL_MAX, true, true);
00669       o_name = prefix_ + "nlp_solve_frequency";
00670       options_->SetIntegerValue(o_name.c_str(), 0, true, true);
00671       o_name = prefix_ + "fp_pass_infeasible";
00672       options_->SetStringValue(o_name.c_str(), "yes", true, true);
00673       //o_name = prefix_ + "cutoff_decr";
00674       //options_->SetNumericValue(o_name.c_str(), 1e-02, true, true);
00675       intParam_[BabLogLevel] = 0;
00676     }
00677     else if (algo==B_QG) {
00678       std::string o_name = prefix_ + "oa_decomposition";
00679       options_->SetStringValue(o_name.c_str(),"no", true, true);
00680       o_name = prefix_ + "pump_for_minlp";
00681       options_->SetStringValue(o_name.c_str(),"no", true, true);
00682       o_name = prefix_ + "nlp_solve_frequency";
00683       options_->SetIntegerValue(o_name.c_str(), 0, true, true);
00684     }
00685     else if (algo==B_Ecp) {
00686       std::string o_name = prefix_ + "oa_decomposition";
00687       options_->SetStringValue(o_name.c_str(),"no", true, true);
00688       o_name = prefix_ + "pump_for_minlp";
00689       options_->SetStringValue(o_name.c_str(),"no", true, true);
00690       o_name = prefix_ + "nlp_solve_frequency";
00691       options_->SetIntegerValue(o_name.c_str(), 0, true, true);
00692       o_name = prefix_ + "filmint_ecp_cuts";
00693       options_->SetIntegerValue(o_name.c_str(), 1, true, true);
00694       o_name = prefix_ + "number_cut_passes";
00695       options_->SetIntegerValue(o_name.c_str(), 1, true, true);
00696     }
00697 //#define GREAT_STUFF_FOR_ANDREAS
00698 #ifdef GREAT_STUFF_FOR_ANDREAS
00699     printf("ToDo: Clean me up in Bab::branchAndBound\n");
00700     OsiCuts cuts;
00701     nonlinearSolver_->getOuterApproximation(cuts, true, NULL, true);
00702     continuousSolver_->applyCuts(cuts);
00703 #endif
00704 
00705 
00706     int varSelection;
00707     options_->GetEnumValue("variable_selection",varSelection,prefix_.c_str());
00708     if (varSelection > RELIABILITY_BRANCHING) {
00709       std::cout<<"Variable selection stragey not available with oa branch-and-cut."<<std::endl;
00710     }
00711     /* Populate cut generation and heuristic procedures.*/
00712     int ival;
00713     options_->GetIntegerValue("nlp_solve_frequency",ival,prefix_.c_str());
00714     if (ival != 0) {
00715       CuttingMethod cg;
00716       cg.frequency = ival;
00717       OaNlpOptim * nlpsol = new OaNlpOptim(*this);
00718       nlpsol->passInMessageHandler(messageHandler_);
00719       cg.cgl = nlpsol;
00720       cg.id="NLP solution based oa cuts";
00721       cutGenerators_.push_back(cg);
00722     }
00723 
00724     options_->GetIntegerValue("filmint_ecp_cuts",ival, prefix_.c_str());
00725     if (ival != 0) {
00726       CuttingMethod cg;
00727       cg.frequency = ival;
00728       EcpCuts * ecp = new EcpCuts(*this);
00729       ecp->passInMessageHandler(messageHandler_);
00730       cg.cgl = ecp;
00731       cg.id = "Ecp cuts";
00732       cutGenerators_.push_back(cg);
00733     }
00734 
00735     if (algo == B_Hyb || algo == B_Ecp)
00736       addMilpCutGenerators();
00737 
00738     int doFp;
00739     options_->GetEnumValue("pump_for_minlp",doFp,prefix_.c_str());
00740     if (doFp) {
00741       CuttingMethod cg;
00742       cg.frequency = -99;
00743       MinlpFeasPump * oa = new MinlpFeasPump(*this);
00744       oa->passInMessageHandler(messageHandler_);
00745       cg.cgl = oa;
00746       cg.id = "Feasibility Pump for MINLP.";
00747       cutGenerators_.push_back(cg);
00748 
00749     }
00750     int doOa;
00751     options_->GetEnumValue("oa_decomposition",doOa,prefix_.c_str());
00752     if (doOa) {
00753       CuttingMethod cg;
00754       cg.frequency = -99;
00755       OACutGenerator2 * oa = new OACutGenerator2(*this);
00756       oa->passInMessageHandler(messageHandler_);
00757       cg.cgl = oa;
00758       cg.id = "Outer Approximation decomposition.";
00759       cutGenerators_.push_back(cg);
00760 
00761     }
00762 
00763     {
00764       CuttingMethod cg;
00765       cg.frequency = 1;
00766       OaFeasibilityChecker * oa = new OaFeasibilityChecker(*this);
00767       oa->passInMessageHandler(messageHandler_);
00768       oa->setReassignLpSolver(false);
00769       cg.cgl = oa;
00770       cg.id = "Outer Approximation feasibility check.";
00771       cg.atSolution = false;
00772       cg.normal = true;
00773       cg.always = true;
00774       cutGenerators_.push_back(cg);
00775     }
00776 
00777     {
00778       CuttingMethod cg;
00779       cg.frequency = 1;
00780       OaFeasibilityChecker * oa = new OaFeasibilityChecker(*this);
00781       oa->passInMessageHandler(messageHandler_);
00782       oa->setReassignLpSolver(true);
00783       cg.cgl = oa;
00784       cg.id = "Outer Approximation strong branching solution check.";
00785       cg.atSolution = true;
00786       cg.normal = false;
00787       cutGenerators_.push_back(cg);
00788     }
00789 
00790     DummyHeuristic * oaHeu = new DummyHeuristic;
00791     oaHeu->setNlp(nonlinearSolver_);
00792     HeuristicMethod h;
00793     h.heuristic = oaHeu;
00794     h.id = "nonlinear programm";
00795     heuristics_.push_back(h);
00796 
00797     Ipopt::Index doHeuristicRINS = false;
00798     options()->GetEnumValue("heuristic_RINS",doHeuristicRINS,prefix_.c_str());
00799     if(doHeuristicRINS){
00800       HeuristicRINS* rins = new HeuristicRINS(this);
00801       HeuristicMethod h;
00802       h.heuristic = rins;
00803       h.id = "RINS";
00804       heuristics_.push_back(h);
00805     }
00806 
00807     Ipopt::Index doHeuristicLocalBranching = false;
00808     options()->GetEnumValue("heuristic_local_branching",doHeuristicLocalBranching,prefix_.c_str());
00809     if(doHeuristicLocalBranching){
00810       HeuristicLocalBranching* local_branching = new HeuristicLocalBranching(this);
00811       HeuristicMethod h;
00812       h.heuristic = local_branching;
00813       h.id = "LocalBranching";
00814       heuristics_.push_back(h);
00815     }
00816 
00817     Ipopt::Index doHeuristicFPump = false;
00818     options()->GetEnumValue("heuristic_feasibility_pump",doHeuristicFPump,prefix_.c_str());
00819     if(doHeuristicFPump){
00820       HeuristicFPump* feasibility_pump = new HeuristicFPump(this);
00821       HeuristicMethod h;
00822       h.heuristic = feasibility_pump;
00823       h.id = "FPump";
00824       heuristics_.push_back(h);
00825     }
00826 
00827     Ipopt::Index doHeuristicDiveFractional = false;
00828     options()->GetEnumValue("heuristic_dive_fractional",doHeuristicDiveFractional,prefix_.c_str());
00829     if(doHeuristicDiveFractional){
00830       HeuristicDiveFractional* dive_fractional = new HeuristicDiveFractional(this);
00831       HeuristicMethod h;
00832       h.heuristic = dive_fractional;
00833       h.id = "DiveFractional";
00834       heuristics_.push_back(h);
00835     }
00836 
00837     Ipopt::Index doHeuristicDiveVectorLength = false;
00838     options()->GetEnumValue("heuristic_dive_vectorLength",doHeuristicDiveVectorLength,prefix_.c_str());
00839     if(doHeuristicDiveVectorLength){
00840       HeuristicDiveVectorLength* dive_vectorLength = new HeuristicDiveVectorLength(this);
00841       HeuristicMethod h;
00842       h.heuristic = dive_vectorLength;
00843       h.id = "DiveVectorLength";
00844       heuristics_.push_back(h);
00845     }
00846 
00847     Ipopt::Index doHeuristicDiveMIPFractional = false;
00848     options()->GetEnumValue("heuristic_dive_MIP_fractional",doHeuristicDiveMIPFractional,prefix_.c_str());
00849     if(doHeuristicDiveMIPFractional){
00850       HeuristicDiveMIPFractional* dive_MIP_fractional = new HeuristicDiveMIPFractional(this);
00851       HeuristicMethod h;
00852       h.heuristic = dive_MIP_fractional;
00853       h.id = "DiveMIPFractional";
00854       heuristics_.push_back(h);
00855     }
00856 
00857     Ipopt::Index doHeuristicDiveMIPVectorLength = false;
00858     options()->GetEnumValue("heuristic_dive_MIP_vectorLength",doHeuristicDiveMIPVectorLength,prefix_.c_str());
00859     if(doHeuristicDiveMIPVectorLength){
00860       HeuristicDiveMIPVectorLength* dive_MIP_vectorLength = new HeuristicDiveMIPVectorLength(this);
00861       HeuristicMethod h;
00862       h.heuristic = dive_MIP_vectorLength;
00863       h.id = "DiveMIPVectorLength";
00864       heuristics_.push_back(h);
00865     }
00866 
00867 #if 0
00868     if(true){
00869       InnerApproximation * inner = new InnerApproximation(this);
00870       HeuristicMethod h;
00871       h.heuristic = inner;
00872       h.id = "InnerApproximation";
00873       heuristics_.push_back(h);
00874     }
00875 #endif
00876     setup_time += CoinCpuTime();
00877     doubleParam_[MaxTime] -= setup_time;
00878   }
00879 
00880 
00881   Algorithm BonminSetup::getAlgorithm()
00882   {
00883     if (algo_ != Dummy)
00884       return algo_;
00885     if (IsValid(options_)) {
00886       int ival;
00887       options_->GetEnumValue("algorithm", ival,prefix_.c_str());
00888       return Algorithm(ival);
00889     }
00890     else return Algorithm(3);
00891   }
00892 
00893 }/* end namespace Bonmin*/
00894 

Generated on Wed Nov 30 03:03:52 2011 by  doxygen 1.4.7