00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "BonminConfig.h"
00011 #ifdef COIN_HAS_FILTERSQP
00012 # include "BonFilterSolver.hpp"
00013 #endif
00014 #include "BonBabSetupBase.hpp"
00015 #include <climits>
00016 #include <fstream>
00017 #include <sstream>
00018
00019 #include "BonDiver.hpp"
00020 #include "BonQpBranchingSolver.hpp"
00021 #include "BonLpBranchingSolver.hpp"
00022 #include "BonChooseVariable.hpp"
00023 #include "BonTMINLP2Quad.hpp"
00024 #include "BonTMINLPLinObj.hpp"
00025 namespace Bonmin
00026 {
00027 int BabSetupBase::defaultIntParam_[BabSetupBase::NumberIntParam] = {
00028 1 ,
00029 100 ,
00030 2 ,
00031 0 ,
00032 0 ,
00033 5 ,
00034 2 ,
00035 COIN_INT_MAX ,
00036 COIN_INT_MAX ,
00037 COIN_INT_MAX ,
00038 0 ,
00039 0 ,
00040 1 ,
00041 20 ,
00042 0
00043 };
00044
00045
00046 double BabSetupBase::defaultDoubleParam_[BabSetupBase::NumberDoubleParam] = {
00047 0 ,
00048 COIN_DBL_MAX ,
00049 0 ,
00050 0 ,
00051 1e-09 ,
00052 COIN_DBL_MAX ,
00053 };
00054
00055 BabSetupBase::BabSetupBase(const CoinMessageHandler * handler):
00056 nonlinearSolver_(NULL),
00057 continuousSolver_(NULL),
00058 cutGenerators_(),
00059 heuristics_(),
00060 branchingMethod_(NULL),
00061 nodeComparisonMethod_(),
00062 treeTraversalMethod_(),
00063 objects_(0),
00064 journalist_(NULL),
00065 options_(NULL),
00066 roptions_(NULL),
00067 readOptions_(false),
00068 messageHandler_(NULL),
00069 prefix_("bonmin.")
00070 {
00071 CoinCopyN(defaultIntParam_, NumberIntParam, intParam_);
00072 CoinCopyN(defaultDoubleParam_, NumberDoubleParam, doubleParam_);
00073 if(handler) messageHandler_ = handler->clone();
00074 }
00075
00077 BabSetupBase::BabSetupBase(const BabSetupBase & other):
00078 nonlinearSolver_(NULL),
00079 continuousSolver_(NULL),
00080 cutGenerators_(),
00081 heuristics_(),
00082 branchingMethod_(NULL),
00083 nodeComparisonMethod_(other.nodeComparisonMethod_),
00084 treeTraversalMethod_(other.treeTraversalMethod_),
00085 objects_(other.objects_),
00086 journalist_(other.journalist_),
00087 options_(NULL),
00088 roptions_(other.roptions_),
00089 readOptions_(other.readOptions_),
00090 messageHandler_(NULL),
00091 prefix_(other.prefix_)
00092 {
00093 if (other.nonlinearSolver_) {
00094 nonlinearSolver_ = static_cast<OsiTMINLPInterface *>(other.nonlinearSolver_->clone());
00095 }
00096 if (other.continuousSolver_) {
00097 continuousSolver_ = other.continuousSolver_->clone();
00098 }
00099 if (other.messageHandler_) {
00100 messageHandler_ = other.messageHandler_->clone();
00101 continuousSolver_->passInMessageHandler(messageHandler_);
00102 }
00103 for (CuttingMethods::const_iterator i = other.cutGenerators_.begin() ; i != other.cutGenerators_.end() ; i++) {
00104 cutGenerators_.push_back(*i);
00105 cutGenerators_.back().cgl = cutGenerators_.back().cgl->clone();
00106 }
00107
00108 for (HeuristicMethods::iterator i = heuristics_.begin() ; i != heuristics_.end() ; i++) {
00109 heuristics_.push_back(*i);
00110 heuristics_.back().heuristic = i->heuristic->clone();
00111 }
00112
00113 if(other.branchingMethod_ != NULL)
00114 branchingMethod_ = other.branchingMethod_->clone();
00115 if (IsValid(other.options_)) {
00116 options_ = new OptionsList;
00117 *options_ = *other.options_;
00118 }
00119 CoinCopyN(other.intParam_, NumberIntParam, intParam_);
00120 CoinCopyN(other.doubleParam_, NumberDoubleParam, doubleParam_);
00121 for (unsigned int i = 0 ; i < objects_.size() ; i++) {
00122 objects_[i]->clone();
00123 }
00124 }
00125
00127 BabSetupBase::BabSetupBase(const BabSetupBase & other,
00128 OsiTMINLPInterface &nlp):
00129 nonlinearSolver_(NULL),
00130 continuousSolver_(NULL),
00131 cutGenerators_(),
00132 heuristics_(),
00133 branchingMethod_(NULL),
00134 nodeComparisonMethod_(other.nodeComparisonMethod_),
00135 treeTraversalMethod_(other.treeTraversalMethod_),
00136 objects_(other.objects_),
00137 journalist_(other.journalist_),
00138 options_(NULL),
00139 roptions_(other.roptions_),
00140 readOptions_(other.readOptions_),
00141 messageHandler_(NULL),
00142 prefix_(other.prefix_)
00143 {
00144 nonlinearSolver_ = &nlp;
00145 if (other.continuousSolver_ != other.nonlinearSolver_) {
00146 continuousSolver_ = NULL;
00147 }
00148 else
00149 continuousSolver_ = nonlinearSolver_;
00150 if (other.messageHandler_) {
00151 messageHandler_ = other.messageHandler_->clone();
00152 continuousSolver_->passInMessageHandler(messageHandler_);
00153 }
00154 for (CuttingMethods::const_iterator i = other.cutGenerators_.begin() ; i != other.cutGenerators_.end() ; i++) {
00155 cutGenerators_.push_back(*i);
00156 cutGenerators_.back().cgl = cutGenerators_.back().cgl->clone();
00157 }
00158
00159 for (HeuristicMethods::iterator i = heuristics_.begin() ; i != heuristics_.end() ; i++) {
00160 heuristics_.push_back(*i);
00161 heuristics_.back().heuristic = i->heuristic->clone();
00162 }
00163
00164 if(other.branchingMethod_ != NULL)
00165 branchingMethod_ = other.branchingMethod_->clone();
00166 if (IsValid(other.options_)) {
00167 options_ = new OptionsList;
00168 *options_ = *other.options_;
00169 }
00170 CoinCopyN(other.intParam_, NumberIntParam, intParam_);
00171 CoinCopyN(other.doubleParam_, NumberDoubleParam, doubleParam_);
00172 for (unsigned int i = 0 ; i < objects_.size() ; i++) {
00173 objects_[i]->clone();
00174 }
00175 }
00177 BabSetupBase::BabSetupBase(const BabSetupBase & other,
00178 OsiTMINLPInterface &nlp,
00179 const std::string & prefix):
00180 nonlinearSolver_(other.nonlinearSolver_),
00181 continuousSolver_(NULL),
00182 cutGenerators_(),
00183 heuristics_(),
00184 branchingMethod_(NULL),
00185 nodeComparisonMethod_(),
00186 treeTraversalMethod_(),
00187 objects_(other.objects_),
00188 journalist_(other.journalist_),
00189 options_(NULL),
00190 roptions_(other.roptions_),
00191 readOptions_(other.readOptions_),
00192 messageHandler_(NULL),
00193 prefix_(prefix)
00194 {
00195 nonlinearSolver_ = &nlp;
00196 if (IsValid(other.options_)) {
00197 options_ = new OptionsList;
00198 *options_ = *other.options_;
00199 }
00200 if (other.messageHandler_) {
00201 messageHandler_ = other.messageHandler_->clone();
00202 nonlinearSolver_->passInMessageHandler(messageHandler_);
00203 }
00204 CoinCopyN(defaultIntParam_, NumberIntParam, intParam_);
00205 CoinCopyN(defaultDoubleParam_, NumberDoubleParam, doubleParam_);
00206 gatherParametersValues(options_);
00207 for (unsigned int i = 0 ; i < objects_.size() ; i++) {
00208 objects_[i]->clone();
00209 }
00210 }
00211
00212 BabSetupBase::BabSetupBase(Ipopt::SmartPtr<TMINLP> tminlp, const CoinMessageHandler * handler):
00213 nonlinearSolver_(NULL),
00214 continuousSolver_(NULL),
00215 cutGenerators_(),
00216 heuristics_(),
00217 branchingMethod_(NULL),
00218 nodeComparisonMethod_(),
00219 treeTraversalMethod_(),
00220 objects_(0),
00221 readOptions_(false),
00222 messageHandler_(NULL),
00223 prefix_("bonmin.")
00224 {
00225 CoinCopyN(defaultIntParam_, NumberIntParam, intParam_);
00226 CoinCopyN(defaultDoubleParam_, NumberDoubleParam, doubleParam_);
00227 if(handler) messageHandler_ = handler->clone();
00228 use(tminlp);
00229 }
00230
00231
00233 BabSetupBase *
00234 BabSetupBase::clone(OsiTMINLPInterface&nlp)const {
00235 throw(CoinError("BabSetupBase", "CloneWithOtherNlp","Not implemented"));
00236 }
00237
00238
00239 void
00240 BabSetupBase::use(Ipopt::SmartPtr<TMINLP> tminlp)
00241 {
00242 readOptionsFile();
00243 assert(IsValid(tminlp));
00244 nonlinearSolver_ = new OsiTMINLPInterface;
00245 int ival;
00246 options_->GetEnumValue("enable_dynamic_nlp", ival, "bonmin.");
00247 if(ival && ! tminlp->hasLinearObjective()){
00248 Ipopt::SmartPtr<Bonmin::TMINLPLinObj> linObj =
00249 new Bonmin::TMINLPLinObj;
00250 linObj->setTminlp(GetRawPtr(tminlp));
00251 tminlp = GetRawPtr(linObj);
00252 }
00253 nonlinearSolver_->initialize(roptions_, options_, journalist_, prefix(), tminlp);
00254 if(messageHandler_ != NULL)
00255 nonlinearSolver_->passInMessageHandler(messageHandler_);
00256 else
00257 messageHandler_ = nonlinearSolver_->messageHandler()->clone();
00258 if (ival){
00259 nonlinearSolver_->use(new Bonmin::TMINLP2TNLPQuadCuts(tminlp));
00260 }
00261 }
00262
00263 BabSetupBase::BabSetupBase(const OsiTMINLPInterface& nlp):
00264 nonlinearSolver_(NULL),
00265 continuousSolver_(NULL),
00266 cutGenerators_(),
00267 heuristics_(),
00268 branchingMethod_(NULL),
00269 nodeComparisonMethod_(),
00270 treeTraversalMethod_(),
00271 objects_(0),
00272 journalist_(NULL),
00273 options_(NULL),
00274 roptions_(NULL),
00275 readOptions_(false),
00276 messageHandler_(NULL),
00277 prefix_("bonmin.")
00278 {
00279 CoinCopyN(defaultIntParam_, NumberIntParam, intParam_);
00280 CoinCopyN(defaultDoubleParam_, NumberDoubleParam, doubleParam_);
00281 use(nlp);
00282 }
00283
00284 void
00285 BabSetupBase::use(const OsiTMINLPInterface& nlp)
00286 {
00287 nonlinearSolver_ = dynamic_cast<OsiTMINLPInterface *>(nlp.clone());
00288 options_ = nonlinearSolver_->solver()->options();
00289 roptions_ = nonlinearSolver_->solver()->roptions();
00290 journalist_ = nonlinearSolver_->solver()->journalist();
00291 if(messageHandler_ != NULL ) delete messageHandler_;
00292 messageHandler_ = nlp.messageHandler()->clone();
00293 readOptions_ = true;
00294 }
00295
00296 BabSetupBase::BabSetupBase( Ipopt::SmartPtr<TNLPSolver> app):
00297 nonlinearSolver_(NULL),
00298 continuousSolver_(NULL),
00299 cutGenerators_(),
00300 heuristics_(),
00301 branchingMethod_(NULL),
00302 nodeComparisonMethod_(),
00303 treeTraversalMethod_(),
00304 objects_(0),
00305 journalist_(app->journalist()),
00306 options_(app->options()),
00307 roptions_(app->roptions()),
00308 readOptions_(true),
00309 messageHandler_(NULL),
00310 prefix_("bonmin.")
00311 {
00312 CoinCopyN(defaultIntParam_, NumberIntParam, intParam_);
00313 CoinCopyN(defaultDoubleParam_, NumberDoubleParam, doubleParam_);
00314 }
00315
00316
00317 BabSetupBase::~BabSetupBase()
00318 {
00319 if (nonlinearSolver_ != continuousSolver_) {
00320 delete nonlinearSolver_;
00321 }
00322 delete continuousSolver_;
00323 delete branchingMethod_;
00324 for (CuttingMethods::iterator i = cutGenerators_.begin() ; i != cutGenerators_.end() ; i++) {
00325 delete i->cgl;
00326 i->cgl = NULL;
00327 }
00328
00329 for (HeuristicMethods::iterator i = heuristics_.begin() ; i != heuristics_.end() ; i++) {
00330 delete i->heuristic;
00331 }
00332
00333 for (unsigned int i = 0 ; i < objects_.size() ; i++) {
00334 delete objects_[i];
00335 }
00336
00337 if(messageHandler_)
00338 delete messageHandler_;
00339 }
00340
00341
00342 void
00343 BabSetupBase::gatherParametersValues(Ipopt::SmartPtr<OptionsList> options)
00344 {
00345
00346 options->GetIntegerValue("bb_log_level",intParam_[BabLogLevel],prefix_.c_str());
00347 options->GetIntegerValue("bb_log_interval",intParam_[BabLogInterval],prefix_.c_str());
00348 options->GetIntegerValue("max_consecutive_failures",intParam_[MaxFailures],prefix_.c_str());
00349 options->GetEnumValue("nlp_failure_behavior",intParam_[FailureBehavior],prefix_.c_str());
00350 options->GetIntegerValue("max_consecutive_infeasible",intParam_[MaxInfeasible],prefix_.c_str());
00351 options->GetIntegerValue("number_strong_branch",intParam_[NumberStrong],prefix_.c_str());
00352 options->GetIntegerValue("number_before_trust",intParam_[MinReliability],prefix_.c_str());
00353 options->GetIntegerValue("node_limit",intParam_[MaxNodes],prefix_.c_str());
00354 options->GetIntegerValue("solution_limit",intParam_[MaxSolutions],prefix_.c_str());
00355 options->GetIntegerValue("iteration_limit",intParam_[MaxIterations],prefix_.c_str());
00356 options->GetEnumValue("sos_constraints",intParam_[DisableSos],prefix_.c_str());
00357 options->GetIntegerValue("num_cut_passes",intParam_[NumCutPasses],prefix_.c_str());
00358 options->GetIntegerValue("num_cut_passes_at_root",intParam_[NumCutPassesAtRoot],prefix_.c_str());
00359 options->GetIntegerValue("nlp_log_at_root",intParam_[RootLogLevel],prefix_.c_str());
00360
00361 options->GetNumericValue("cutoff_decr",doubleParam_[CutoffDecr],prefix_.c_str());
00362 options->GetNumericValue("cutoff",doubleParam_[Cutoff],prefix_.c_str());
00363 options->GetNumericValue("allowable_gap",doubleParam_[AllowableGap],prefix_.c_str());
00364 options->GetNumericValue("allowable_fraction_gap",doubleParam_[AllowableFractionGap],prefix_.c_str());
00365 options->GetNumericValue("integer_tolerance",doubleParam_[IntTol],prefix_.c_str());
00366 options->GetNumericValue("time_limit", doubleParam_[MaxTime],prefix_.c_str());
00367
00368
00369 int ival;
00370 options->GetEnumValue("node_comparison",ival,prefix_.c_str());
00371 nodeComparisonMethod_ = NodeComparison(ival);
00372
00373 options->GetEnumValue("tree_search_strategy", ival, prefix_.c_str());
00374 treeTraversalMethod_ = TreeTraversal(ival);
00375
00376 int varSelection;
00377 options->GetEnumValue("variable_selection",varSelection,prefix_.c_str());
00378
00379 if (varSelection == MOST_FRACTIONAL) {
00380 intParam_[NumberStrong] = 0;
00381 intParam_[MinReliability] = 0;
00382 options_->SetIntegerValue("bonmin.number_strong_branch",intParam_[BabSetupBase::NumberStrong],true,true);
00383 }
00384 else if (varSelection == RELIABILITY_BRANCHING) {
00385 intParam_[MinReliability] = 10;
00386 options_->SetIntegerValue("bonmin.number_before_trust",intParam_[BabSetupBase::MinReliability],true,true);
00387 }
00388 }
00389
00390 void
00391 BabSetupBase::registerOptions()
00392 {
00393 registerAllOptions(roptions_);
00394 }
00395
00396 void
00397 BabSetupBase::registerAllOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions)
00398 {
00399 OsiTMINLPInterface::registerOptions(roptions);
00400
00401 roptions->SetRegisteringCategory("Output ond log-levels options", RegisteredOptions::BonminCategory);
00402
00403 roptions->AddBoundedIntegerOption("bb_log_level",
00404 "specify main branch-and-bound log level.",
00405 0,5,1,
00406 "Set the level of output of the branch-and-bound : "
00407 "0 - none, 1 - minimal, 2 - normal low, 3 - normal high"
00408 );
00409 roptions->setOptionExtraInfo("bb_log_level", 127);
00410
00411 roptions->AddLowerBoundedIntegerOption("bb_log_interval",
00412 "Interval at which node level output is printed.",
00413 0,100,
00414 "Set the interval (in terms of number of nodes) at which "
00415 "a log on node resolutions (consisting of lower and upper bounds) is given.");
00416 roptions->setOptionExtraInfo("bb_log_interval", 127);
00417
00418 roptions->AddBoundedIntegerOption("lp_log_level",
00419 "specify LP log level.",
00420 0,4,0,
00421 "Set the level of output of the linear programming sub-solver in B-Hyb or B-QG : "
00422 "0 - none, 1 - minimal, 2 - normal low, 3 - normal high, 4 - verbose"
00423 );
00424 roptions->setOptionExtraInfo("lp_log_level", 119);
00425
00426 roptions->AddBoundedIntegerOption("nlp_log_at_root"," Specify a different log level "
00427 "for root relaxtion.",
00428 0,12,0,
00429 "");
00430 roptions->setOptionExtraInfo("nlp_log_at_root",63);
00431
00432 roptions->SetRegisteringCategory("Branch-and-bound options", RegisteredOptions::BonminCategory);
00433
00434 roptions->AddLowerBoundedNumberOption("time_limit",
00435 "Set the global maximum computation time (in secs) for the algorithm.",
00436 0.,0,1e10,
00437 "");
00438 roptions->setOptionExtraInfo("time_limit", 127);
00439
00440 roptions->AddLowerBoundedIntegerOption("node_limit",
00441 "Set the maximum number of nodes explored in the branch-and-bound search.",
00442 0,COIN_INT_MAX,
00443 "");
00444 roptions->setOptionExtraInfo("node_limit", 127);
00445
00446 roptions->AddLowerBoundedIntegerOption("iteration_limit",
00447 "Set the cumulated maximum number of iteration in the algorithm used to process nodes continuous relaxations in the branch-and-bound.",
00448 0,COIN_INT_MAX,
00449 "value 0 deactivates option.");
00450 roptions->setOptionExtraInfo("iteration_limit", 127);
00451
00452 roptions->AddLowerBoundedIntegerOption("solution_limit",
00453 "Abort after that much integer feasible solution have been found by algorithm",
00454 0,COIN_INT_MAX,
00455 "value 0 deactivates option");
00456 roptions->setOptionExtraInfo("solution_limit", 127);
00457
00458 roptions->AddLowerBoundedNumberOption("integer_tolerance",
00459 "Set integer tolerance.",
00460 0.,1,1e-06,
00461 "Any number within that value of an integer is considered integer.");
00462 roptions->setOptionExtraInfo("integer_tolerance", 127);
00463
00464 roptions->AddBoundedNumberOption("allowable_gap",
00465 "Specify the value of absolute gap under which the algorithm stops.",
00466 -1.e20,0,1.e20,0,0.,
00467 "Stop the tree search when the gap between the objective value of the best known solution"
00468 " and the best bound on the objective of any solution is less than this.");
00469 roptions->setOptionExtraInfo("allowable_gap", 127);
00470
00471 roptions->AddBoundedNumberOption("allowable_fraction_gap",
00472 "Specify the value of relative gap under which the algorithm stops.",
00473 -1.e20,0,1.e20,0,0.0,
00474 "Stop the tree search when the gap between the objective value of the best known solution "
00475 "and the best bound on the objective of any solution is less than this "
00476 "fraction of the absolute value of the best known solution value.");
00477 roptions->setOptionExtraInfo("allowable_fraction_gap", 127);
00478
00479 roptions->AddBoundedNumberOption("cutoff",
00480 "Specify cutoff value.",
00481 -1e100,0,1e100,0,1e100,
00482 "cutoff should be the value of a feasible solution known by the user "
00483 "(if any). The algorithm will only look for solutions better than cutoof.");
00484 roptions->setOptionExtraInfo("cutoff", 127);
00485
00486
00487 roptions->AddBoundedNumberOption("cutoff_decr",
00488 "Specify cutoff decrement.",
00489 -1e10,0,1e10,0,1e-05,
00490 "Specify the amount by which cutoff is decremented below "
00491 "a new best upper-bound"
00492 " (usually a small positive value but in non-convex problems it may be a negative value).");
00493 roptions->setOptionExtraInfo("cutoff_decr", 127);
00494
00495
00496 roptions->AddStringOption5("node_comparison",
00497 "Choose the node selection strategy.",
00498 "best-bound",
00499 "best-bound", "choose node with the smallest bound,",
00500 "depth-first", "Perform depth first search,",
00501 "breadth-first", "Perform breadth first search,",
00502 "dynamic", "Cbc dynamic strategy (starts with a depth first search and turn to best bound after 3 "
00503 "integer feasible solutions have been found).",
00504 "best-guess", "choose node with smallest guessed integer solution",
00505 "Choose the strategy for selecting the next node to be processed.");
00506 roptions->setOptionExtraInfo("node_comparison", 63);
00507
00508 roptions->AddStringOption5("tree_search_strategy",
00509 "Pick a strategy for traversing the tree",
00510 "probed-dive",
00511 "top-node"," Always pick the top node as sorted by the node comparison function",
00512 "dive","Dive in the tree if possible, otherwise pick top node as sorted by the tree comparison function.",
00513 "probed-dive","Dive in the tree exploring two childs before continuing the dive at each level.",
00514 "dfs-dive","Dive in the tree if possible doing a depth first search. "
00515 "Backtrack on leaves or when a prescribed depth is attained or "
00516 "when estimate of best possible integer feasible solution in subtree "
00517 "is worst than cutoff. "
00518 "Once a prescribed limit of backtracks is attained pick top node "
00519 "as sorted by the tree comparison function",
00520 "dfs-dive-dynamic","Same as dfs-dive but once enough solution are found switch to best-bound and if too many nodes switch to depth-first.",
00521 "All strategies can be used in conjunction with any of the node comparison functions. "
00522 "Options which affect dfs-dive are max-backtracks-in-dive and max-dive-depth. "
00523 "The dfs-dive won't work in a non-convex problem where objective does not decrease down branches."
00524 );
00525 roptions->setOptionExtraInfo("tree_search_strategy", 63);
00526
00527 roptions->AddLowerBoundedIntegerOption("number_strong_branch",
00528 "Choose the maximum number of variables considered for strong branching.",
00529 0,20,
00530 "Set the number of variables on which to do strong branching.");
00531 roptions->setOptionExtraInfo("number_strong_branch", 127);
00532
00533
00534 roptions->AddLowerBoundedIntegerOption
00535 ("number_before_trust",
00536 "Set the number of branches on a variable before its pseudo costs are to be believed "
00537 "in dynamic strong branching.",
00538 0,8,
00539 "A value of 0 disables pseudo costs.");
00540 roptions->setOptionExtraInfo("number_before_trust", 127);
00541
00542 roptions->AddStringOption2("nlp_failure_behavior",
00543 "Set the behavior when an NLP or a series of NLP are unsolved by Ipopt (we call unsolved an NLP for which Ipopt is not "
00544 "able to guarantee optimality within the specified tolerances).",
00545 "stop",
00546 "stop", "Stop when failure happens.",
00547 "fathom", "Continue when failure happens.",
00548 "If set to \"fathom\", the algorithm will fathom the node when Ipopt fails to find a solution to the nlp "
00549 "at that node whithin the specified tolerances. "
00550 "The algorithm then becomes a heuristic, and the user will be warned that the solution might not be optimal.");
00551 roptions->setOptionExtraInfo("nlp_failure_behavior", 8);
00552
00553 roptions->AddStringOption2("sos_constraints",
00554 "Wether or not to activate SOS constraints.",
00555 "enable",
00556 "enable","",
00557 "disable","",
00558 "(only type 1 SOS are supported at the moment)");
00559 roptions->setOptionExtraInfo("sos_constraints", 63);
00560
00561 roptions->AddStringOption10("variable_selection",
00562 "Chooses variable selection strategy",
00563 "strong-branching",
00564 "most-fractional", "Choose most fractional variable",
00565 "strong-branching", "Perform strong branching",
00566 "reliability-branching", "Use reliability branching",
00567 "curvature-estimator", "Use curvature estimation to select branching variable",
00568 "qp-strong-branching", "Perform strong branching with QP approximation",
00569 "lp-strong-branching", "Perform strong branching with LP approximation",
00570 "nlp-strong-branching", "Perform strong branching with NLP approximation",
00571 "osi-simple", "Osi method to do simple branching",
00572 "osi-strong", "Osi method to do strong branching",
00573 "random", "Method to choose branching variable randomly");
00574
00575 roptions->setOptionExtraInfo("variable_selection", 8);
00576
00577 roptions->AddLowerBoundedIntegerOption("num_cut_passes",
00578 "Set the maximum number of cut passes at regular nodes of the branch-and-cut.",
00579 0,1,
00580 "");
00581 roptions->setOptionExtraInfo("num_cut_passes", 19);
00582
00583 roptions->AddLowerBoundedIntegerOption("num_cut_passes_at_root",
00584 "Set the maximum number of cut passes at regular nodes of the branch-and-cut.",
00585 0,20,
00586 "");
00587 roptions->setOptionExtraInfo("num_cut_passes_at_root", 19);
00588
00589 roptions->AddStringOption2("enable_dynamic_nlp",
00590 "Enable dynamic linear and quadratic rows addition in nlp",
00591 "no",
00592 "no", "",
00593 "yes", "",
00594 "");
00595 roptions->setOptionExtraInfo("enable_dynamic_nlp", 19);
00596
00597
00598 LpBranchingSolver::registerOptions(roptions);
00599
00600 #ifdef COIN_HAS_FILTERSQP
00601 FilterSolver::registerOptions(roptions);
00602 BqpdSolver::registerOptions(roptions);
00603 #endif
00604 CbcDiver::registerOptions(roptions);
00605 CbcDfsDiver::registerOptions(roptions);
00606 BonChooseVariable::registerOptions(roptions);
00607 }
00608
00609
00611 void
00612 BabSetupBase::initializeOptionsAndJournalist()
00613 {
00614 options_ = new Ipopt::OptionsList();
00615
00616 journalist_= new Ipopt::Journalist();
00617 roptions_ = new Bonmin::RegisteredOptions();
00618
00619 try {
00620 Ipopt::SmartPtr<Ipopt::Journal> stdout_journal =
00621 journalist_->AddFileJournal("console", "stdout", Ipopt::J_ITERSUMMARY);
00622
00623 options_->SetJournalist(journalist_);
00624 options_->SetRegisteredOptions(GetRawPtr(roptions_));
00625 }
00626 catch (Ipopt::IpoptException &E) {
00627 E.ReportException(*journalist_);
00628 throw E;
00629 }
00630 catch (std::bad_alloc) {
00631 journalist_->Printf(Ipopt::J_ERROR, Ipopt::J_MAIN, "\n Not enough memory .... EXIT\n");
00632 throw -1;
00633 }
00634 catch (...) {
00635 Ipopt::IpoptException E("Uncaught exception in FilterSolver::FilterSolver()",
00636 "BonFilterSolver.cpp",-1);
00637 throw E;
00638 }
00639
00640 registerOptions();
00641 }
00642
00644 void
00645 BabSetupBase::readOptionsFile(std::string fileName)
00646 {
00647 if (GetRawPtr(options_) == NULL || GetRawPtr(roptions_) == NULL || GetRawPtr(journalist_) == NULL)
00648 initializeOptionsAndJournalist();
00649 std::ifstream is;
00650 if (fileName != "") {
00651 try {
00652 is.open(fileName.c_str());
00653 }
00654 catch (std::bad_alloc) {
00655 journalist_->Printf(Ipopt::J_SUMMARY, Ipopt::J_MAIN, "\nEXIT: Not enough memory.\n");
00656 throw -1;
00657 }
00658 catch (...) {
00659 Ipopt::IpoptException E("Unknown Exception caught in ipopt", "Unknown File", -1);
00660 E.ReportException(*journalist_);
00661 throw -1;
00662 }
00663 }
00664 readOptionsStream(is);
00665 if (is) {
00666 is.close();
00667 }
00668 }
00669
00671 void
00672 BabSetupBase::readOptionsString(std::string opt_string)
00673 {
00674 if (GetRawPtr(options_) == NULL || GetRawPtr(roptions_) == NULL || GetRawPtr(journalist_) == NULL)
00675 initializeOptionsAndJournalist();
00676 std::stringstream is(opt_string.c_str());
00677 readOptionsStream(is);
00678 }
00679
00680
00681 void
00682 BabSetupBase::readOptionsStream(std::istream& is)
00683 {
00684 if (GetRawPtr(options_) == NULL || GetRawPtr(roptions_) == NULL || GetRawPtr(journalist_) == NULL)
00685 initializeOptionsAndJournalist();
00686 if (is.good()) {
00687 try {
00688 options_->ReadFromStream(*journalist_, is);
00689 }
00690 catch (Ipopt::IpoptException &E) {
00691 E.ReportException(*journalist_);
00692 throw E;
00693 }
00694 }
00695 mayPrintDoc();
00696 readOptions_=true;
00697 }
00698
00700 void
00701 BabSetupBase::mayPrintDoc()
00702 {
00703 bool print_options_documentation;
00704 options_->GetBoolValue("print_options_documentation",
00705 print_options_documentation, "");
00706 if (print_options_documentation) {
00707 std::list<std::string> categories;
00708 categories.push_back("Bonmin algorithm choice");
00709 categories.push_back("bonmin output options");
00710 categories.push_back("bonmin options for robustness");
00711 categories.push_back("bonmin options for non-convex problems");
00712 categories.push_back("bonmin branch-and-bound options");
00713 categories.push_back("Diving options");
00714 categories.push_back("bonmin options : B-Hyb specific options");
00715 categories.push_back("bonmin options : Options for OA decomposition");
00716 categories.push_back("bonmin options : Outer Approximation cuts");
00717 categories.push_back("bonmin options : Options for MILP subsolver in OA decomposition");
00718 categories.push_back("bonmin options for MILP cutting planes");
00719 categories.push_back("bonmin options : Options for ecp cuts generation");
00720 categories.push_back("Bonmin ecp based strong branching");
00721 categories.push_back("bonmin options : Nlp solve options");
00722 categories.push_back("bonmin nlp interface option");
00723 categories.push_back("bonmin experimental options");
00724 #ifdef COIN_HAS_FILTERSQP
00725 categories.push_back("FilterSQP options");
00726 #endif
00727
00728 roptions_->OutputOptionDocumentation(*(journalist_),categories);
00729 }
00730 }
00731
00732 void
00733 BabSetupBase::setPriorities()
00734 {
00735 const int * priorities = nonlinearSolver()->getPriorities();
00736 const double * upPsCosts = nonlinearSolver()->getUpPsCosts();
00737 const int * directions = nonlinearSolver()->getBranchingDirections();
00738 bool hasPseudo = (upPsCosts!=NULL);
00739 if (priorities == NULL && directions && NULL && hasPseudo)
00740 return;
00741 int n = nonlinearSolver()->numberObjects();
00742 OsiObject ** objects = nonlinearSolver()->objects();
00743 for (int i = 0 ; i < n; i++) {
00744 OsiObject2 * object = dynamic_cast<OsiObject2 *>(objects[i]);
00745 int iCol = objects[i]->columnNumber();
00746 if (iCol < 0) {
00747 throw CoinError("BabSetupBase","setPriorities",
00748 "Don't know how to set priority for non-column object.");
00749 }
00750 if (priorities) {
00751 objects[i]->setPriority(priorities[iCol]);
00752 }
00753 if (directions) {
00754 if (object == NULL) {
00755 throw CoinError("BabSetupBase","setPriorities",
00756 "Don't know how to set preferred way for object.");
00757 }
00758 object->setPreferredWay(directions[iCol]);
00759 }
00760 if (upPsCosts) {
00761 throw CoinError("BabSetupBase","setPriorities",
00762 "Can not handle user set pseudo-costs with OsiObjects\n"
00763 "You should use one of the Cbc branching rules:\n"
00764 "most-fractional or strong-branching.");
00765 }
00766 }
00767 }
00768
00769 void
00770 BabSetupBase::addSos()
00771 {
00772
00773
00774 const TMINLP::SosInfo * sos = nonlinearSolver()->model()->sosConstraints();
00775 if (!getIntParameter(BabSetupBase::DisableSos) && sos && sos->num > 0)
00776 {
00777 const int & numSos = sos->num;
00778 OsiObject ** objects = new OsiObject*[numSos];
00779 const int * starts = sos->starts;
00780 const int * indices = sos->indices;
00781 const char * types = sos->types;
00782 const double * weights = sos->weights;
00783 bool hasPriorities = false;
00784 const int * varPriorities = nonlinearSolver()->getPriorities();
00785 int numberObjects = nonlinearSolver()->numberObjects();
00786 if (varPriorities)
00787 {
00788 for (int i = 0 ; i < numberObjects ; i++) {
00789 if (varPriorities[i]) {
00790 hasPriorities = true;
00791 break;
00792 }
00793 }
00794 }
00795 const int * sosPriorities = sos->priorities;
00796 if (sosPriorities)
00797 {
00798 for (int i = 0 ; i < numSos ; i++) {
00799 if (sosPriorities[i]) {
00800 hasPriorities = true;
00801 break;
00802 }
00803 }
00804 }
00805 for (int i = 0 ; i < numSos ; i++)
00806 {
00807 int start = starts[i];
00808 int length = starts[i + 1] - start;
00809 objects[i] = new OsiSOS(nonlinearSolver(), length, &indices[start],
00810 &weights[start], (int) types[i]);
00811
00812 objects[i]->setPriority(10);
00813 if (hasPriorities && sosPriorities && sosPriorities[i]) {
00814 objects[i]->setPriority(sosPriorities[i]);
00815 }
00816 }
00817 nonlinearSolver()->addObjects(numSos, objects);
00818 for (int i = 0 ; i < numSos ; i++)
00819 delete objects[i];
00820 delete [] objects;
00821 }
00822 }
00823
00824
00825 }
00826