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

Generated on Tue Sep 30 03:01:22 2008 by  doxygen 1.4.7