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 algorithm", RegisteredOptions::BonminCategory);
00193
00194 roptions->AddLowerBoundedIntegerOption("Gomory_cuts",
00195 "Frequency (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 }
00700
00701 #ifdef GREAT_STUFF_FOR_ANDREAS
00702 printf("ToDo: Clean me up in Bab::branchAndBound\n");
00703 OsiCuts cuts;
00704 nonlinearSolver_->getOuterApproximation(cuts, true, NULL, true);
00705 continuousSolver_->applyCuts(cuts);
00706 #endif
00707
00708
00709 int varSelection;
00710 options_->GetEnumValue("variable_selection",varSelection,prefix_.c_str());
00711 if (varSelection > RELIABILITY_BRANCHING) {
00712 switch (varSelection){
00713 case OSI_SIMPLE:
00714 continuousSolver_->findIntegersAndSOS(false);
00715 setPriorities();
00716 addSos();
00717 branchingMethod_ = new OsiChooseVariable(nonlinearSolver_);
00718
00719 break;
00720 case OSI_STRONG:
00721 {
00722 continuousSolver_->findIntegersAndSOS(false);
00723 setPriorities();
00724 addSos();
00725 OsiChooseStrong * chooser = new OsiChooseStrong(nonlinearSolver_);
00726 branchingMethod_ = chooser;
00727 chooser->setNumberStrong(intParam_[NumberStrong]);
00728 chooser->setTrustStrongForSolution(false);
00729 chooser->setNumberBeforeTrusted(intParam_[MinReliability]);
00730 }
00731 break;
00732 default:
00733 std::cout<<"Variable selection stragey not available with oa branch-and-cut."<<std::endl;
00734 break;
00735 }
00736 }
00737
00738 int ival;
00739 options_->GetIntegerValue("nlp_solve_frequency",ival,prefix_.c_str());
00740 if (ival != 0) {
00741 CuttingMethod cg;
00742 cg.frequency = ival;
00743 OaNlpOptim * nlpsol = new OaNlpOptim(*this);
00744 nlpsol->passInMessageHandler(messageHandler_);
00745 cg.cgl = nlpsol;
00746 cg.id="NLP solution based oa cuts";
00747 cutGenerators_.push_back(cg);
00748 }
00749
00750 options_->GetIntegerValue("filmint_ecp_cuts",ival, prefix_.c_str());
00751 if (ival != 0) {
00752 CuttingMethod cg;
00753 cg.frequency = ival;
00754 EcpCuts * ecp = new EcpCuts(*this);
00755 ecp->passInMessageHandler(messageHandler_);
00756 cg.cgl = ecp;
00757 cg.id = "Ecp cuts";
00758 cutGenerators_.push_back(cg);
00759 }
00760
00761 if (algo == B_Hyb || algo == B_Ecp)
00762 addMilpCutGenerators();
00763
00764 int doFp;
00765 options_->GetEnumValue("pump_for_minlp",doFp,prefix_.c_str());
00766 if (doFp) {
00767 CuttingMethod cg;
00768 cg.frequency = -99;
00769 MinlpFeasPump * oa = new MinlpFeasPump(*this);
00770 oa->passInMessageHandler(messageHandler_);
00771 cg.cgl = oa;
00772 cg.id = "Feasibility Pump for MINLP.";
00773 cutGenerators_.push_back(cg);
00774
00775 }
00776 int doOa;
00777 options_->GetEnumValue("oa_decomposition",doOa,prefix_.c_str());
00778 if (doOa) {
00779 CuttingMethod cg;
00780 cg.frequency = -99;
00781 OACutGenerator2 * oa = new OACutGenerator2(*this);
00782 oa->passInMessageHandler(messageHandler_);
00783 cg.cgl = oa;
00784 cg.id = "Outer Approximation decomposition.";
00785 cutGenerators_.push_back(cg);
00786
00787 }
00788
00789 {
00790 CuttingMethod cg;
00791 cg.frequency = 1;
00792 OaFeasibilityChecker * oa = new OaFeasibilityChecker(*this);
00793 oa->passInMessageHandler(messageHandler_);
00794 oa->setReassignLpSolver(false);
00795 cg.cgl = oa;
00796 cg.id = "Outer Approximation feasibility check.";
00797 cg.atSolution = false;
00798 cg.normal = true;
00799 cg.always = true;
00800 cutGenerators_.push_back(cg);
00801 }
00802
00803 {
00804 CuttingMethod cg;
00805 cg.frequency = 1;
00806 OaFeasibilityChecker * oa = new OaFeasibilityChecker(*this);
00807 oa->passInMessageHandler(messageHandler_);
00808 oa->setReassignLpSolver(true);
00809 cg.cgl = oa;
00810 cg.id = "Outer Approximation strong branching solution check.";
00811 cg.atSolution = true;
00812 cg.normal = false;
00813 cutGenerators_.push_back(cg);
00814 }
00815
00816 DummyHeuristic * oaHeu = new DummyHeuristic;
00817 oaHeu->setNlp(nonlinearSolver_);
00818 HeuristicMethod h;
00819 h.heuristic = oaHeu;
00820 h.id = "nonlinear programm";
00821 heuristics_.push_back(h);
00822
00823 Ipopt::Index doHeuristicRINS = false;
00824 options()->GetEnumValue("heuristic_RINS",doHeuristicRINS,prefix_.c_str());
00825 if(doHeuristicRINS){
00826 HeuristicRINS* rins = new HeuristicRINS(this);
00827 HeuristicMethod h;
00828 h.heuristic = rins;
00829 h.id = "RINS";
00830 heuristics_.push_back(h);
00831 }
00832
00833 Ipopt::Index doHeuristicLocalBranching = false;
00834 options()->GetEnumValue("heuristic_local_branching",doHeuristicLocalBranching,prefix_.c_str());
00835 if(doHeuristicLocalBranching){
00836 HeuristicLocalBranching* local_branching = new HeuristicLocalBranching(this);
00837 HeuristicMethod h;
00838 h.heuristic = local_branching;
00839 h.id = "LocalBranching";
00840 heuristics_.push_back(h);
00841 }
00842
00843 Ipopt::Index doHeuristicFPump = false;
00844 options()->GetEnumValue("heuristic_feasibility_pump",doHeuristicFPump,prefix_.c_str());
00845 if(doHeuristicFPump){
00846 HeuristicFPump* feasibility_pump = new HeuristicFPump(this);
00847 HeuristicMethod h;
00848 h.heuristic = feasibility_pump;
00849 h.id = "FPump";
00850 heuristics_.push_back(h);
00851 }
00852
00853 Ipopt::Index doHeuristicDiveFractional = false;
00854 options()->GetEnumValue("heuristic_dive_fractional",doHeuristicDiveFractional,prefix_.c_str());
00855 if(doHeuristicDiveFractional){
00856 HeuristicDiveFractional* dive_fractional = new HeuristicDiveFractional(this);
00857 HeuristicMethod h;
00858 h.heuristic = dive_fractional;
00859 h.id = "DiveFractional";
00860 heuristics_.push_back(h);
00861 }
00862
00863 Ipopt::Index doHeuristicDiveVectorLength = false;
00864 options()->GetEnumValue("heuristic_dive_vectorLength",doHeuristicDiveVectorLength,prefix_.c_str());
00865 if(doHeuristicDiveVectorLength){
00866 HeuristicDiveVectorLength* dive_vectorLength = new HeuristicDiveVectorLength(this);
00867 HeuristicMethod h;
00868 h.heuristic = dive_vectorLength;
00869 h.id = "DiveVectorLength";
00870 heuristics_.push_back(h);
00871 }
00872
00873 Ipopt::Index doHeuristicDiveMIPFractional = false;
00874 options()->GetEnumValue("heuristic_dive_MIP_fractional",doHeuristicDiveMIPFractional,prefix_.c_str());
00875 if(doHeuristicDiveMIPFractional){
00876 HeuristicDiveMIPFractional* dive_MIP_fractional = new HeuristicDiveMIPFractional(this);
00877 HeuristicMethod h;
00878 h.heuristic = dive_MIP_fractional;
00879 h.id = "DiveMIPFractional";
00880 heuristics_.push_back(h);
00881 }
00882
00883 Ipopt::Index doHeuristicDiveMIPVectorLength = false;
00884 options()->GetEnumValue("heuristic_dive_MIP_vectorLength",doHeuristicDiveMIPVectorLength,prefix_.c_str());
00885 if(doHeuristicDiveMIPVectorLength){
00886 HeuristicDiveMIPVectorLength* dive_MIP_vectorLength = new HeuristicDiveMIPVectorLength(this);
00887 HeuristicMethod h;
00888 h.heuristic = dive_MIP_vectorLength;
00889 h.id = "DiveMIPVectorLength";
00890 heuristics_.push_back(h);
00891 }
00892
00893 #if 0
00894 if(true){
00895 InnerApproximation * inner = new InnerApproximation(this);
00896 HeuristicMethod h;
00897 h.heuristic = inner;
00898 h.id = "InnerApproximation";
00899 heuristics_.push_back(h);
00900 }
00901 #endif
00902 setup_time += CoinCpuTime();
00903 doubleParam_[MaxTime] -= setup_time;
00904 }
00905
00906
00907 Algorithm BonminSetup::getAlgorithm()
00908 {
00909 if (algo_ != Dummy)
00910 return algo_;
00911 if (IsValid(options_)) {
00912 int ival;
00913 options_->GetEnumValue("algorithm", ival,prefix_.c_str());
00914 return Algorithm(ival);
00915 }
00916 else return Algorithm(3);
00917 }
00918
00919 }
00920