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