/home/coin/SVN-release/OS-2.1.1/Bonmin/src/Algorithms/BonBabSetupBase.cpp

Go to the documentation of this file.
00001 // (C) Copyright International Business Machines Corporation 2007
00002 // All Rights Reserved.
00003 // This code is published under the Common Public License.
00004 //
00005 // Authors :
00006 // Pierre Bonami, International Business Machines Corporation
00007 //
00008 // Date : 04/12/2007
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 /* BabLogLevel*/,
00029         100 /* BabLogInterval*/,
00030         2 /* MaxFailures.*/,
00031         0 /* FailureBehavior.*/,
00032         0 /* MaxInfeasible*/,
00033         5 /*NumberStrong*/,
00034         2 /* MinReliability*/,
00035         COIN_INT_MAX /* MaxNodes*/,
00036         COIN_INT_MAX /* MaxSolutions*/,
00037         COIN_INT_MAX /* MaxIterations*/,
00038         0 /* SpecialOption*/,
00039         0 /* DisableSos.*/,
00040         1 /* numCutPasses.*/,
00041         20 /* numCutPassesAtRoot.*/,
00042         0 /* log level at root.*/
00043       };
00044 
00045 
00046   double BabSetupBase::defaultDoubleParam_[BabSetupBase::NumberDoubleParam] = {
00047         0 /* CutoffDecr*/,
00048         COIN_DBL_MAX /* Cutoff*/,
00049         0 /* AllowableGap*/,
00050         0 /*AllowableFractionGap*/,
00051         1e-09 /*IntTol*/,
00052         COIN_DBL_MAX /* MaxTime*/,
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     // Set branching strategy
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     /* BabSetup options.*/
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     /* Branching options.*/
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       //    roptions->OutputLatexOptionDocumentation2(*app_->Jnlst(),categories);
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     // pass user set Sos constraints (code inspired from CoinSolve.cpp)
00774     const TMINLP::SosInfo * sos = nonlinearSolver()->model()->sosConstraints();
00775     if (!getIntParameter(BabSetupBase::DisableSos) && sos && sos->num > 0) //we have some sos constraints
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 }/* End namespace Bonmin.*/
00826 

Generated on Mon May 3 03:05:13 2010 by  doxygen 1.4.7