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