00001
00002
00003
00004
00005
00006
00007
00008
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
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
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
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
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
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 )
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 )
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
00299 probe->setMaxProbe(10);
00300 probe->setMaxProbeRoot(50);
00301
00302 probe->setMaxLook(10);
00303 probe->setMaxLookRoot(50);
00304 probe->setMaxLookRoot(10);
00305
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
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){
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
00444 chooseVariable->setOnlyPseudoWhenTrusted(false);
00445 break;
00446 #endif
00447 case QP_STRONG_BRANCHING:
00448 chooseVariable->setTrustStrongForSolution(false);
00449 strong_solver = new QpBranchingSolver(nonlinearSolver_);
00450
00451
00452 chooseVariable->setTrustStrongForBound(false);
00453
00454 chooseVariable->setOnlyPseudoWhenTrusted(false);
00455 break;
00456 case LP_STRONG_BRANCHING:
00457 chooseVariable->setTrustStrongForSolution(false);
00458 strong_solver = new LpBranchingSolver(this);
00459
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
00492
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 )
00620 {
00621 double setup_time = -CoinCpuTime();
00622 if (createContinuousSolver) {
00623
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
00632 if(IsValid(linearizer_))
00633 nonlinearSolver_->set_linearizer(linearizer_);
00634
00635 nonlinearSolver_->extractLinearRelaxation(*continuousSolver_);
00636 nonlinearSolver_->setSolverOutputToDefault();
00637
00638
00639 OsiBabSolver * extraStuff = new OsiBabSolver(3);
00640 continuousSolver_->setAuxiliaryInfo(extraStuff);
00641 delete extraStuff;
00642 }
00643 Algorithm algo = getAlgorithm();
00644 std::string prefix = (prefix_ == "bonmin.") ? "" : prefix_;
00645 if (algo == B_Hyb) {
00646 std::string o_name = prefix_ + "oa_decomposition";
00647 options_->SetStringValue(o_name.c_str(),"no", true, true);
00648 o_name = prefix_ + "pump_for_minlp";
00649 options_->SetStringValue(o_name.c_str(),"yes", true, true);
00650 o_name = prefix + "pump_for_minlp.time_limit";
00651 options_->SetNumericValue(o_name.c_str(),10, true, true);
00652 o_name = prefix + "pump_for_minlp.solution_limit";
00653 options_->SetIntegerValue(o_name.c_str(),3, true, true);
00654 }
00655 else if (algo == B_OA) {
00656 std::string o_name = prefix_ + "oa_decomposition";
00657 options_->SetStringValue(o_name.c_str(),"yes", true, true);
00658 o_name = prefix + "oa_decomposition.time_limit";
00659 options_->SetNumericValue(o_name.c_str(),DBL_MAX, true, true);
00660 o_name = prefix_ + "pump_for_minlp";
00661 options_->SetStringValue(o_name.c_str(),"no", true, true);
00662 o_name = prefix + "nlp_solve_frequency";
00663 options_->SetIntegerValue(o_name.c_str(), 0, true, true);
00664 o_name = prefix + "bb_log_level";
00665 options_->SetIntegerValue(o_name.c_str(), 0, true, true);
00666 }
00667 else if (algo == B_IFP) {
00668 std::string o_name = prefix_ + "oa_decomposition";
00669 options_->SetStringValue(o_name.c_str(),"no", true, true);
00670 o_name = prefix_ + "pump_for_minlp";
00671 options_->SetStringValue(o_name.c_str(),"yes", true, true);
00672 o_name = prefix + "pump_for_minlp.time_limit";
00673 options_->SetNumericValue(o_name.c_str(),DBL_MAX, true, true);
00674 o_name = prefix_ + "nlp_solve_frequency";
00675 options_->SetIntegerValue(o_name.c_str(), 0, true, true);
00676 o_name = prefix_ + "fp_pass_infeasible";
00677 options_->SetStringValue(o_name.c_str(), "yes", true, true);
00678
00679
00680 intParam_[BabLogLevel] = 0;
00681 }
00682 else if (algo==B_QG) {
00683 std::string o_name = prefix_ + "oa_decomposition";
00684 options_->SetStringValue(o_name.c_str(),"no", true, true);
00685 o_name = prefix_ + "pump_for_minlp";
00686 options_->SetStringValue(o_name.c_str(),"no", true, true);
00687 o_name = prefix_ + "nlp_solve_frequency";
00688 options_->SetIntegerValue(o_name.c_str(), 0, true, true);
00689 }
00690 else if (algo==B_Ecp) {
00691 std::string o_name = prefix_ + "oa_decomposition";
00692 options_->SetStringValue(o_name.c_str(),"no", true, true);
00693 o_name = prefix_ + "pump_for_minlp";
00694 options_->SetStringValue(o_name.c_str(),"no", true, true);
00695 o_name = prefix_ + "nlp_solve_frequency";
00696 options_->SetIntegerValue(o_name.c_str(), 0, true, true);
00697 o_name = prefix_ + "filmint_ecp_cuts";
00698 options_->SetIntegerValue(o_name.c_str(), 1, true, true);
00699 o_name = prefix_ + "number_cut_passes";
00700 options_->SetIntegerValue(o_name.c_str(), 1, true, true);
00701 }
00702
00703 #ifdef GREAT_STUFF_FOR_ANDREAS
00704 printf("ToDo: Clean me up in Bab::branchAndBound\n");
00705 OsiCuts cuts;
00706 nonlinearSolver_->getOuterApproximation(cuts, true, NULL, true);
00707 continuousSolver_->applyCuts(cuts);
00708 #endif
00709
00710
00711 int varSelection;
00712 options_->GetEnumValue("variable_selection",varSelection,prefix_.c_str());
00713 if (varSelection > RELIABILITY_BRANCHING) {
00714 switch (varSelection){
00715 case OSI_SIMPLE:
00716 continuousSolver_->findIntegersAndSOS(false);
00717 setPriorities();
00718 addSos();
00719 branchingMethod_ = new OsiChooseVariable(nonlinearSolver_);
00720
00721 break;
00722 case OSI_STRONG:
00723 {
00724 continuousSolver_->findIntegersAndSOS(false);
00725 setPriorities();
00726 addSos();
00727 OsiChooseStrong * chooser = new OsiChooseStrong(nonlinearSolver_);
00728 branchingMethod_ = chooser;
00729 chooser->setNumberStrong(intParam_[NumberStrong]);
00730 chooser->setTrustStrongForSolution(false);
00731 chooser->setNumberBeforeTrusted(intParam_[MinReliability]);
00732 }
00733 break;
00734 default:
00735 std::cout<<"Variable selection stragey not available with oa branch-and-cut."<<std::endl;
00736 break;
00737 }
00738 }
00739
00740 int ival;
00741 options_->GetIntegerValue("nlp_solve_frequency",ival,prefix_.c_str());
00742 if (ival != 0) {
00743 CuttingMethod cg;
00744 cg.frequency = ival;
00745 OaNlpOptim * nlpsol = new OaNlpOptim(*this);
00746 nlpsol->passInMessageHandler(messageHandler_);
00747 cg.cgl = nlpsol;
00748 cg.id="NLP solution based oa cuts";
00749 cutGenerators_.push_back(cg);
00750 }
00751
00752 options_->GetIntegerValue("filmint_ecp_cuts",ival, prefix_.c_str());
00753 if (ival != 0) {
00754 CuttingMethod cg;
00755 cg.frequency = ival;
00756 EcpCuts * ecp = new EcpCuts(*this);
00757 ecp->passInMessageHandler(messageHandler_);
00758 cg.cgl = ecp;
00759 cg.id = "Ecp cuts";
00760 cutGenerators_.push_back(cg);
00761 }
00762
00763 if (algo == B_Hyb || algo == B_Ecp)
00764 addMilpCutGenerators();
00765
00766 int doFp;
00767 options_->GetEnumValue("pump_for_minlp",doFp,prefix_.c_str());
00768 if (doFp) {
00769 CuttingMethod cg;
00770 cg.frequency = -99;
00771 MinlpFeasPump * oa = new MinlpFeasPump(*this);
00772 oa->passInMessageHandler(messageHandler_);
00773 cg.cgl = oa;
00774 cg.id = "Feasibility Pump for MINLP.";
00775 cutGenerators_.push_back(cg);
00776
00777 }
00778 int doOa;
00779 options_->GetEnumValue("oa_decomposition",doOa,prefix_.c_str());
00780 if (doOa) {
00781 CuttingMethod cg;
00782 cg.frequency = -99;
00783 OACutGenerator2 * oa = new OACutGenerator2(*this);
00784 oa->passInMessageHandler(messageHandler_);
00785 cg.cgl = oa;
00786 cg.id = "Outer Approximation decomposition.";
00787 cutGenerators_.push_back(cg);
00788
00789 }
00790
00791 {
00792 CuttingMethod cg;
00793 cg.frequency = 1;
00794 OaFeasibilityChecker * oa = new OaFeasibilityChecker(*this);
00795 oa->passInMessageHandler(messageHandler_);
00796 oa->setReassignLpSolver(false);
00797 cg.cgl = oa;
00798 cg.id = "Outer Approximation feasibility check.";
00799 cg.atSolution = false;
00800 cg.normal = true;
00801 cg.always = true;
00802 cutGenerators_.push_back(cg);
00803 }
00804
00805 {
00806 CuttingMethod cg;
00807 cg.frequency = 1;
00808 OaFeasibilityChecker * oa = new OaFeasibilityChecker(*this);
00809 oa->passInMessageHandler(messageHandler_);
00810 oa->setReassignLpSolver(true);
00811 cg.cgl = oa;
00812 cg.id = "Outer Approximation strong branching solution check.";
00813 cg.atSolution = true;
00814 cg.normal = false;
00815 cutGenerators_.push_back(cg);
00816 }
00817
00818 DummyHeuristic * oaHeu = new DummyHeuristic;
00819 oaHeu->setNlp(nonlinearSolver_);
00820 HeuristicMethod h;
00821 h.heuristic = oaHeu;
00822 h.id = "nonlinear programm";
00823 heuristics_.push_back(h);
00824
00825 Ipopt::Index doHeuristicRINS = false;
00826 options()->GetEnumValue("heuristic_RINS",doHeuristicRINS,prefix_.c_str());
00827 if(doHeuristicRINS){
00828 HeuristicRINS* rins = new HeuristicRINS(this);
00829 HeuristicMethod h;
00830 h.heuristic = rins;
00831 h.id = "RINS";
00832 heuristics_.push_back(h);
00833 }
00834
00835 Ipopt::Index doHeuristicLocalBranching = false;
00836 options()->GetEnumValue("heuristic_local_branching",doHeuristicLocalBranching,prefix_.c_str());
00837 if(doHeuristicLocalBranching){
00838 HeuristicLocalBranching* local_branching = new HeuristicLocalBranching(this);
00839 HeuristicMethod h;
00840 h.heuristic = local_branching;
00841 h.id = "LocalBranching";
00842 heuristics_.push_back(h);
00843 }
00844
00845 Ipopt::Index doHeuristicFPump = false;
00846 options()->GetEnumValue("heuristic_feasibility_pump",doHeuristicFPump,prefix_.c_str());
00847 if(doHeuristicFPump){
00848 HeuristicFPump* feasibility_pump = new HeuristicFPump(this);
00849 HeuristicMethod h;
00850 h.heuristic = feasibility_pump;
00851 h.id = "FPump";
00852 heuristics_.push_back(h);
00853 }
00854
00855 Ipopt::Index doHeuristicDiveFractional = false;
00856 options()->GetEnumValue("heuristic_dive_fractional",doHeuristicDiveFractional,prefix_.c_str());
00857 if(doHeuristicDiveFractional){
00858 HeuristicDiveFractional* dive_fractional = new HeuristicDiveFractional(this);
00859 HeuristicMethod h;
00860 h.heuristic = dive_fractional;
00861 h.id = "DiveFractional";
00862 heuristics_.push_back(h);
00863 }
00864
00865 Ipopt::Index doHeuristicDiveVectorLength = false;
00866 options()->GetEnumValue("heuristic_dive_vectorLength",doHeuristicDiveVectorLength,prefix_.c_str());
00867 if(doHeuristicDiveVectorLength){
00868 HeuristicDiveVectorLength* dive_vectorLength = new HeuristicDiveVectorLength(this);
00869 HeuristicMethod h;
00870 h.heuristic = dive_vectorLength;
00871 h.id = "DiveVectorLength";
00872 heuristics_.push_back(h);
00873 }
00874
00875 Ipopt::Index doHeuristicDiveMIPFractional = false;
00876 options()->GetEnumValue("heuristic_dive_MIP_fractional",doHeuristicDiveMIPFractional,prefix_.c_str());
00877 if(doHeuristicDiveMIPFractional){
00878 HeuristicDiveMIPFractional* dive_MIP_fractional = new HeuristicDiveMIPFractional(this);
00879 HeuristicMethod h;
00880 h.heuristic = dive_MIP_fractional;
00881 h.id = "DiveMIPFractional";
00882 heuristics_.push_back(h);
00883 }
00884
00885 Ipopt::Index doHeuristicDiveMIPVectorLength = false;
00886 options()->GetEnumValue("heuristic_dive_MIP_vectorLength",doHeuristicDiveMIPVectorLength,prefix_.c_str());
00887 if(doHeuristicDiveMIPVectorLength){
00888 HeuristicDiveMIPVectorLength* dive_MIP_vectorLength = new HeuristicDiveMIPVectorLength(this);
00889 HeuristicMethod h;
00890 h.heuristic = dive_MIP_vectorLength;
00891 h.id = "DiveMIPVectorLength";
00892 heuristics_.push_back(h);
00893 }
00894
00895 #if 0
00896 if(true){
00897 InnerApproximation * inner = new InnerApproximation(this);
00898 HeuristicMethod h;
00899 h.heuristic = inner;
00900 h.id = "InnerApproximation";
00901 heuristics_.push_back(h);
00902 }
00903 #endif
00904 setup_time += CoinCpuTime();
00905 doubleParam_[MaxTime] -= setup_time;
00906 }
00907
00908
00909 Algorithm BonminSetup::getAlgorithm()
00910 {
00911 if (algo_ != Dummy)
00912 return algo_;
00913 if (IsValid(options_)) {
00914 int ival;
00915 options_->GetEnumValue("algorithm", ival,prefix_.c_str());
00916 return Algorithm(ival);
00917 }
00918 else return Algorithm(3);
00919 }
00920
00921 }
00922