/home/coin/SVN-release/OS-2.4.0/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 Ipopt::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 Ipopt::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 Ipopt::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<Ipopt::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       options_->SetIntegerValue("bonmin.number_before_trust",intParam_[BabSetupBase::MinReliability],true,true);
00384     }
00385     else if (varSelection == RELIABILITY_BRANCHING) {
00386       intParam_[MinReliability] = 10;
00387       options_->SetIntegerValue("bonmin.number_before_trust",intParam_[BabSetupBase::MinReliability],true,true);
00388     }
00389   }
00390 
00391   void
00392   BabSetupBase::registerOptions()
00393   {
00394     registerAllOptions(roptions_);
00395   }
00396 
00397   void
00398   BabSetupBase::registerAllOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions)
00399   {
00400     OsiTMINLPInterface::registerOptions(roptions);
00401     /* BabSetup options.*/
00402     roptions->SetRegisteringCategory("Output and log-level options", RegisteredOptions::BonminCategory);
00403 
00404     roptions->AddBoundedIntegerOption("bb_log_level",
00405         "specify main branch-and-bound log level.",
00406         0,5,1,
00407         "Set the level of output of the branch-and-bound : "
00408         "0 - none, 1 - minimal, 2 - normal low, 3 - normal high"
00409                                      );
00410     roptions->setOptionExtraInfo("bb_log_level", 127);
00411 
00412     roptions->AddLowerBoundedIntegerOption("bb_log_interval",
00413         "Interval at which node level output is printed.",
00414         0,100,
00415         "Set the interval (in terms of number of nodes) at which "
00416         "a log on node resolutions (consisting of lower and upper bounds) is given.");
00417     roptions->setOptionExtraInfo("bb_log_interval", 127);
00418 
00419     roptions->AddBoundedIntegerOption("lp_log_level",
00420         "specify LP log level.",
00421         0,4,0,
00422         "Set the level of output of the linear programming sub-solver in B-Hyb or B-QG : "
00423         "0 - none, 1 - minimal, 2 - normal low, 3 - normal high, 4 - verbose"
00424                                      );
00425     roptions->setOptionExtraInfo("lp_log_level", 119);
00426 
00427     roptions->AddBoundedIntegerOption("nlp_log_at_root"," Specify a different log level "
00428                                            "for root relaxtion.",
00429                                             0,12,0,
00430                                             "");
00431     roptions->setOptionExtraInfo("nlp_log_at_root",63);
00432 
00433     roptions->SetRegisteringCategory("Branch-and-bound options", RegisteredOptions::BonminCategory);
00434 
00435     roptions->AddLowerBoundedNumberOption("time_limit",
00436         "Set the global maximum computation time (in secs) for the algorithm.",
00437         0.,0,1e10,
00438         "");
00439     roptions->setOptionExtraInfo("time_limit", 127);
00440 
00441     roptions->AddLowerBoundedIntegerOption("node_limit",
00442         "Set the maximum number of nodes explored in the branch-and-bound search.",
00443         0,COIN_INT_MAX,
00444         "");
00445     roptions->setOptionExtraInfo("node_limit", 127);
00446 
00447     roptions->AddLowerBoundedIntegerOption("iteration_limit",
00448         "Set the cumulated maximum number of iteration in the algorithm used to process nodes continuous relaxations in the branch-and-bound.",
00449         0,COIN_INT_MAX,
00450         "value 0 deactivates option.");
00451     roptions->setOptionExtraInfo("iteration_limit", 127);
00452 
00453     roptions->AddLowerBoundedIntegerOption("solution_limit",
00454         "Abort after that much integer feasible solution have been found by algorithm",
00455         0,COIN_INT_MAX,
00456         "value 0 deactivates option");
00457     roptions->setOptionExtraInfo("solution_limit", 127);
00458 
00459     roptions->AddLowerBoundedNumberOption("integer_tolerance",
00460         "Set integer tolerance.",
00461         0.,1,1e-06,
00462         "Any number within that value of an integer is considered integer.");
00463     roptions->setOptionExtraInfo("integer_tolerance", 127);
00464 
00465     roptions->AddBoundedNumberOption("allowable_gap",
00466         "Specify the value of absolute gap under which the algorithm stops.",
00467         -1.e20,0,1.e20,0,0.,
00468         "Stop the tree search when the gap between the objective value of the best known solution"
00469         " and the best bound on the objective of any solution is less than this.");
00470     roptions->setOptionExtraInfo("allowable_gap", 127);
00471 
00472     roptions->AddBoundedNumberOption("allowable_fraction_gap",
00473         "Specify the value of relative gap under which the algorithm stops.",
00474         -1.e20,0,1.e20,0,0.0,
00475         "Stop the tree search when the gap between the objective value of the best known solution "
00476         "and the best bound on the objective of any solution is less than this "
00477         "fraction of the absolute value of the best known solution value.");
00478     roptions->setOptionExtraInfo("allowable_fraction_gap", 127);
00479 
00480     roptions->AddBoundedNumberOption("cutoff",
00481         "Specify cutoff value.",
00482         -1e100,0,1e100,0,1e100,
00483         "cutoff should be the value of a feasible solution known by the user "
00484         "(if any). The algorithm will only look for solutions better than cutoff.");
00485     roptions->setOptionExtraInfo("cutoff", 127);
00486 
00487 
00488     roptions->AddBoundedNumberOption("cutoff_decr",
00489         "Specify cutoff decrement.",
00490         -1e10,0,1e10,0,1e-05,
00491         "Specify the amount by which cutoff is decremented below "
00492         "a new best upper-bound"
00493         " (usually a small positive value but in non-convex problems it may be a negative value).");
00494     roptions->setOptionExtraInfo("cutoff_decr", 127);
00495 
00496 
00497     roptions->AddStringOption5("node_comparison",
00498         "Choose the node selection strategy.",
00499         "best-bound",
00500         "best-bound", "choose node with the smallest bound,",
00501         "depth-first", "Perform depth first search,",
00502         "breadth-first", "Perform breadth first search,",
00503         "dynamic", "Cbc dynamic strategy (starts with a depth first search and turn to best bound after 3 "
00504         "integer feasible solutions have been found).",
00505         "best-guess", "choose node with smallest guessed integer solution",
00506         "Choose the strategy for selecting the next node to be processed.");
00507     roptions->setOptionExtraInfo("node_comparison", 63);
00508 
00509     roptions->AddStringOption5("tree_search_strategy",
00510         "Pick a strategy for traversing the tree",
00511         "probed-dive",
00512         "top-node"," Always pick the top node as sorted by the node comparison function",
00513         "dive","Dive in the tree if possible, otherwise pick top node as sorted by the tree comparison function.",
00514         "probed-dive","Dive in the tree exploring two childs before continuing the dive at each level.",
00515         "dfs-dive","Dive in the tree if possible doing a depth first search. "
00516         "Backtrack on leaves or when a prescribed depth is attained or "
00517         "when estimate of best possible integer feasible solution in subtree "
00518         "is worst than cutoff. "
00519         "Once a prescribed limit of backtracks is attained pick top node "
00520         "as sorted by the tree comparison function",
00521         "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.",
00522         "All strategies can be used in conjunction with any of the node comparison functions. "
00523         "Options which affect dfs-dive are max-backtracks-in-dive and max-dive-depth. "
00524         "The dfs-dive won't work in a non-convex problem where objective does not decrease down branches."
00525                               );
00526     roptions->setOptionExtraInfo("tree_search_strategy", 63);
00527 
00528     roptions->AddLowerBoundedIntegerOption("number_strong_branch",
00529         "Choose the maximum number of variables considered for strong branching.",
00530         0,20,
00531         "Set the number of variables on which to do strong branching.");
00532     roptions->setOptionExtraInfo("number_strong_branch", 127);
00533 
00534  
00535     roptions->AddLowerBoundedIntegerOption
00536     ("number_before_trust",
00537      "Set the number of branches on a variable before its pseudo costs are to be believed "
00538      "in dynamic strong branching.",
00539      0,8,
00540      "A value of 0 disables pseudo costs.");
00541     roptions->setOptionExtraInfo("number_before_trust", 127);
00542 
00543     roptions->AddStringOption2("nlp_failure_behavior",
00544         "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 "
00545         "able to guarantee optimality within the specified tolerances).",
00546         "stop",
00547         "stop", "Stop when failure happens.",
00548         "fathom", "Continue when failure happens.",
00549         "If set to \"fathom\", the algorithm will fathom the node when Ipopt fails to find a solution to the nlp "
00550         "at that node whithin the specified tolerances. "
00551         "The algorithm then becomes a heuristic, and the user will be warned that the solution might not be optimal.");
00552     roptions->setOptionExtraInfo("nlp_failure_behavior", 8);
00553 
00554     roptions->AddStringOption2("sos_constraints",
00555         "Wether or not to activate SOS constraints.",
00556         "enable",
00557         "enable","",
00558         "disable","",
00559         "(only type 1 SOS are supported at the moment)");
00560     roptions->setOptionExtraInfo("sos_constraints", 63);
00561 
00562 #ifdef BONMIN_CURVATURE_BRANCHING
00563     roptions->AddStringOption10("variable_selection",
00564 #else
00565     roptions->AddStringOption9("variable_selection",
00566 #endif
00567         "Chooses variable selection strategy",
00568         "strong-branching",
00569         "most-fractional", "Choose most fractional variable",
00570         "strong-branching", "Perform strong branching",
00571         "reliability-branching", "Use reliability branching",
00572 #ifdef BONMIN_CURVATURE_BRANCHING
00573         "curvature-estimator", "Use curvature estimation to select branching variable",
00574 #endif
00575         "qp-strong-branching", "Perform strong branching with QP approximation",
00576         "lp-strong-branching", "Perform strong branching with LP approximation",
00577         "nlp-strong-branching", "Perform strong branching with NLP approximation",
00578         "osi-simple", "Osi method to do simple branching",
00579         "osi-strong", "Osi method to do strong branching",
00580         "random", "Method to choose branching variable randomly");
00581 
00582     roptions->setOptionExtraInfo("variable_selection", 8);
00583 
00584     roptions->AddLowerBoundedIntegerOption("num_cut_passes",
00585         "Set the maximum number of cut passes at regular nodes of the branch-and-cut.",
00586         0,1,
00587         "");
00588     roptions->setOptionExtraInfo("num_cut_passes", 19);
00589 
00590     roptions->AddLowerBoundedIntegerOption("num_cut_passes_at_root",
00591         "Set the maximum number of cut passes at regular nodes of the branch-and-cut.",
00592         0,20,
00593         "");
00594     roptions->setOptionExtraInfo("num_cut_passes_at_root", 19);
00595 
00596     roptions->AddStringOption2("enable_dynamic_nlp",
00597                "Enable dynamic linear and quadratic rows addition in nlp",
00598                "no",
00599                "no", "",
00600                "yes", "",
00601                "");
00602     roptions->setOptionExtraInfo("enable_dynamic_nlp", 19);
00603 
00604 
00605     //roptions->SetRegisteringCategory("Debugging",RegisteredOptions::UndocumentedCategory);
00606     roptions->AddStringOption2("read_solution_file",
00607                "Read a file with the optimal solution to test if algorithms cuts it.",
00608                "no",
00609                "no","",
00610                "yes","",
00611                "For Debugging purposes only.");
00612     roptions->setOptionExtraInfo("enable_dynamic_nlp", 8);
00613 
00614     /* Branching options.*/
00615     LpBranchingSolver::registerOptions(roptions);
00616 
00617 #ifdef COIN_HAS_FILTERSQP
00618     FilterSolver::registerOptions(roptions);
00619     BqpdSolver::registerOptions(roptions);
00620 #endif
00621     CbcDiver::registerOptions(roptions);
00622     CbcDfsDiver::registerOptions(roptions);
00623     BonChooseVariable::registerOptions(roptions);
00624   }
00625 
00626 
00628   void
00629   BabSetupBase::initializeOptionsAndJournalist()
00630   {
00631     options_ = new Ipopt::OptionsList();
00632 
00633     journalist_= new Ipopt::Journalist();
00634     roptions_ = new Bonmin::RegisteredOptions();
00635 
00636     try {
00637       Ipopt::SmartPtr<Ipopt::Journal> stdout_journal =
00638         journalist_->AddFileJournal("console", "stdout", Ipopt::J_ITERSUMMARY);
00639 
00640       options_->SetJournalist(journalist_);
00641       options_->SetRegisteredOptions(GetRawPtr(roptions_));
00642     }
00643     catch (Ipopt::IpoptException &E) {
00644       E.ReportException(*journalist_);
00645       throw E;
00646     }
00647     catch (std::bad_alloc) {
00648       journalist_->Printf(Ipopt::J_ERROR, Ipopt::J_MAIN, "\n Not enough memory .... EXIT\n");
00649       throw -1;
00650     }
00651     catch (...) {
00652       Ipopt::IpoptException E("Uncaught exception in FilterSolver::FilterSolver()",
00653           "BonFilterSolver.cpp",-1);
00654       throw E;
00655     }
00656 
00657     registerOptions();
00658   }
00659 
00661   void
00662   BabSetupBase::readOptionsFile(std::string fileName)
00663   {
00664     if (GetRawPtr(options_) == NULL || GetRawPtr(roptions_) == NULL || GetRawPtr(journalist_) == NULL)
00665       initializeOptionsAndJournalist();
00666     std::ifstream is;
00667     if (fileName != "") {
00668       try {
00669         is.open(fileName.c_str());
00670       }
00671       catch (std::bad_alloc) {
00672         journalist_->Printf(Ipopt::J_SUMMARY, Ipopt::J_MAIN, "\nEXIT: Not enough memory.\n");
00673         throw -1;
00674       }
00675       catch (...) {
00676         Ipopt::IpoptException E("Unknown Exception caught in ipopt", "Unknown File", -1);
00677         E.ReportException(*journalist_);
00678         throw -1;
00679       }
00680     }
00681     readOptionsStream(is);
00682     if (is) {
00683       is.close();
00684     }
00685   }
00686 
00688   void
00689   BabSetupBase::readOptionsString(std::string opt_string)
00690   {
00691     if (GetRawPtr(options_) == NULL || GetRawPtr(roptions_) == NULL || GetRawPtr(journalist_) == NULL)
00692       initializeOptionsAndJournalist();
00693     std::stringstream is(opt_string.c_str());
00694     readOptionsStream(is);
00695   }
00696 
00697 
00698   void
00699   BabSetupBase::readOptionsStream(std::istream& is)
00700   {
00701     if (GetRawPtr(options_) == NULL || GetRawPtr(roptions_) == NULL || GetRawPtr(journalist_) == NULL)
00702       initializeOptionsAndJournalist();
00703     if (is.good()) {
00704       try {
00705         options_->ReadFromStream(*journalist_, is);
00706       }
00707       catch (Ipopt::IpoptException &E) {
00708         E.ReportException(*journalist_);
00709         throw E;
00710       }
00711     }
00712     mayPrintDoc();
00713     readOptions_=true;
00714   }
00715 
00717   void
00718   BabSetupBase::mayPrintDoc()
00719   {
00720     bool print_options_documentation;
00721     options_->GetBoolValue("print_options_documentation",
00722         print_options_documentation, "");
00723     if (print_options_documentation) {
00724       std::list<std::string> categories;
00725       categories.push_back("Bonmin algorithm choice");
00726       categories.push_back("bonmin output options");
00727       categories.push_back("bonmin options for robustness");
00728       categories.push_back("bonmin options for non-convex problems");
00729       categories.push_back("bonmin branch-and-bound options");
00730       categories.push_back("Diving options");
00731       categories.push_back("bonmin options : B-Hyb specific options");
00732       categories.push_back("bonmin options : Options for OA decomposition");
00733       categories.push_back("bonmin options : Outer Approximation cuts");
00734       categories.push_back("bonmin options : Options for MILP subsolver in OA decomposition");
00735       categories.push_back("bonmin options for MILP cutting planes");
00736       categories.push_back("bonmin options : Options for ecp cuts generation");
00737       categories.push_back("Bonmin ecp based strong branching");
00738       categories.push_back("bonmin options : Nlp solve options");
00739       categories.push_back("bonmin nlp interface option");
00740       categories.push_back("bonmin experimental options");
00741 #ifdef COIN_HAS_FILTERSQP
00742       categories.push_back("FilterSQP options");
00743 #endif
00744       //    roptions->OutputLatexOptionDocumentation2(*app_->Jnlst(),categories);
00745       roptions_->OutputOptionDocumentation(*(journalist_),categories);
00746     }
00747   }
00748 
00749   void
00750   BabSetupBase::setPriorities()
00751   {
00752     const int * priorities = nonlinearSolver()->getPriorities();
00753     const double * upPsCosts = nonlinearSolver()->getUpPsCosts();
00754     const int * directions = nonlinearSolver()->getBranchingDirections();
00755     bool hasPseudo = (upPsCosts!=NULL);
00756     if (priorities == NULL && directions && NULL && hasPseudo)
00757       return;
00758     int n = nonlinearSolver()->numberObjects();
00759     OsiObject ** objects = nonlinearSolver()->objects();
00760     for (int i = 0 ; i < n; i++) {
00761       OsiObject2 * object = dynamic_cast<OsiObject2 *>(objects[i]);
00762       int iCol = objects[i]->columnNumber();
00763       if (iCol < 0) {
00764         throw CoinError("BabSetupBase","setPriorities",
00765             "Don't know how to set priority for non-column object.");
00766       }
00767       if (priorities) {
00768         objects[i]->setPriority(priorities[iCol]);
00769       }
00770       if (directions) {
00771         if (object == NULL) {
00772           throw CoinError("BabSetupBase","setPriorities",
00773               "Don't know how to set preferred way for object.");
00774         }
00775         object->setPreferredWay(directions[iCol]);
00776       }
00777       if (upPsCosts) {
00778         throw CoinError("BabSetupBase","setPriorities",
00779             "Can not handle user set pseudo-costs with OsiObjects\n"
00780             "You should use one of the Cbc branching rules:\n"
00781             "most-fractional or strong-branching.");
00782       }
00783     }
00784   }
00785 
00786   void
00787   BabSetupBase::addSos()
00788   {
00789 
00790     // pass user set Sos constraints (code inspired from CoinSolve.cpp)
00791     const TMINLP::SosInfo * sos = nonlinearSolver()->model()->sosConstraints();
00792     if (!getIntParameter(BabSetupBase::DisableSos) && sos && sos->num > 0) //we have some sos constraints
00793     {
00794       const int & numSos = sos->num;
00795       OsiObject ** objects = new OsiObject*[numSos];
00796       const int * starts = sos->starts;
00797       const int * indices = sos->indices;
00798       const char * types = sos->types;
00799       const double * weights = sos->weights;
00800       bool hasPriorities = false;
00801       const int * varPriorities = nonlinearSolver()->getPriorities();
00802       int numberObjects =  nonlinearSolver()->numberObjects();
00803       if (varPriorities)
00804       {
00805         for (int i = 0 ; i < numberObjects ; i++) {
00806           if (varPriorities[i]) {
00807             hasPriorities = true;
00808             break;
00809           }
00810         }
00811       }
00812       const int * sosPriorities = sos->priorities;
00813       if (sosPriorities)
00814       {
00815         for (int i = 0 ; i < numSos ; i++) {
00816           if (sosPriorities[i]) {
00817             hasPriorities = true;
00818             break;
00819           }
00820         }
00821       }
00822       for (int i = 0 ; i < numSos ; i++)
00823       {
00824         int start = starts[i];
00825         int length = starts[i + 1] - start;
00826         objects[i] = new OsiSOS(nonlinearSolver(), length, &indices[start],
00827             &weights[start], (int) types[i]);
00828 
00829         objects[i]->setPriority(10);
00830         if (hasPriorities && sosPriorities && sosPriorities[i]) {
00831           objects[i]->setPriority(sosPriorities[i]);
00832         }
00833       }
00834       nonlinearSolver()->addObjects(numSos, objects);
00835       for (int i = 0 ; i < numSos ; i++)
00836         delete objects[i];
00837       delete [] objects;
00838     }
00839   }
00840 
00841 
00842 }/* End namespace Bonmin.*/
00843 

Generated on Thu Sep 22 03:05:53 2011 by  doxygen 1.4.7