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 nonlinearSolver_->extractLinearRelaxation(*continuousSolver_);
00632 nonlinearSolver_->setSolverOutputToDefault();
00633
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
00674
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
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
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 }
00894