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