/home/coin/SVN-release/OS-2.0.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 
00024 namespace Bonmin
00025 {
00026   int BabSetupBase::defaultIntParam_[BabSetupBase::NumberIntParam] = {
00027         1 /* BabLogLevel*/,
00028         100 /* BabLogInterval*/,
00029         2 /* MaxFailures.*/,
00030         0 /* FailureBehavior.*/,
00031         0 /* MaxInfeasible*/,
00032         5 /*NumberStrong*/,
00033         2 /* MinReliability*/,
00034         COIN_INT_MAX /* MaxNodes*/,
00035         COIN_INT_MAX /* MaxSolutions*/,
00036         COIN_INT_MAX /* MaxIterations*/,
00037         0 /* SpecialOption*/,
00038         0 /* DisableSos.*/,
00039         1 /* numCutPasses.*/,
00040         20 /* numCutPassesAtRoot.*/
00041       };
00042 
00043 
00044   double BabSetupBase::defaultDoubleParam_[BabSetupBase::NumberDoubleParam] = {
00045         0 /* CutoffDecr*/,
00046         COIN_DBL_MAX /* Cutoff*/,
00047         0 /* AllowableGap*/,
00048         0 /*AllowableFractionGap*/,
00049         1e-09 /*IntTol*/,
00050         COIN_DBL_MAX /* MaxTime*/,
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     // Set branching strategy
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     /* BabSetup options.*/
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     /* Branching options.*/
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       //    roptions->OutputLatexOptionDocumentation2(*app_->Jnlst(),categories);
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     // pass user set Sos constraints (code inspired from CoinSolve.cpp)
00695     const TMINLP::SosInfo * sos = nonlinearSolver()->model()->sosConstraints();
00696     if (!getIntParameter(BabSetupBase::DisableSos) && sos && sos->num > 0) //we have some sos constraints
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 }/* End namespace Bonmin.*/
00747 

Generated on Thu Oct 8 03:02:53 2009 by  doxygen 1.4.7