00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CouenneCutGenerator.hpp"
00012 #include "CouenneDisjCuts.hpp"
00013 #include "CouenneProblem.hpp"
00014
00015 using namespace Ipopt;
00016 using namespace Couenne;
00017
00019 CouenneDisjCuts::CouenneDisjCuts (Bonmin::OsiTMINLPInterface *minlp,
00020 Bonmin::BabSetupBase *base,
00021 CouenneCutGenerator *cg,
00022 OsiChooseVariable *bcv,
00023 bool is_strong,
00024 JnlstPtr journalist,
00025 const Ipopt::SmartPtr<Ipopt::OptionsList> options):
00026 couenneCG_ (cg),
00027 nrootcuts_ (-1),
00028 ntotalcuts_ (0),
00029 septime_ (0.),
00030 objValue_ (-COIN_DBL_MAX),
00031 minlp_ (minlp),
00032 branchingMethod_ (bcv),
00033 isBranchingStrong_ (is_strong),
00034 jnlst_ (journalist),
00035 activeRows_ (false),
00036 activeCols_ (false),
00037 addPreviousCut_ (false),
00038 cpuTime_ (-1.) {
00039
00040 options -> GetNumericValue ("time_limit", cpuTime_, "couenne.");
00041
00042 options -> GetNumericValue ("disj_init_perc", initDisjPercentage_, "couenne.");
00043 options -> GetIntegerValue ("disj_init_number", initDisjNumber_, "couenne.");
00044 options -> GetIntegerValue ("disj_depth_level", depthLevelling_, "couenne.");
00045 options -> GetIntegerValue ("disj_depth_stop", depthStopSeparate_, "couenne.");
00046
00047 std::string s;
00048 options -> GetStringValue ("disj_active_rows", s, "couenne."); activeRows_ = (s == "yes");
00049 options -> GetStringValue ("disj_active_cols", s, "couenne."); activeCols_ = (s == "yes");
00050 options -> GetStringValue ("disj_cumulative", s, "couenne."); addPreviousCut_ = (s == "yes");
00051 }
00052
00053
00055 CouenneDisjCuts::CouenneDisjCuts (const CouenneDisjCuts &src):
00056 couenneCG_ (src.couenneCG_),
00057 nrootcuts_ (src.nrootcuts_),
00058 ntotalcuts_ (src.ntotalcuts_),
00059 septime_ (src.septime_),
00060 objValue_ (src.objValue_),
00061 minlp_ (src.minlp_),
00062 branchingMethod_ (src.branchingMethod_),
00063 isBranchingStrong_ (src.isBranchingStrong_),
00064 jnlst_ (src.jnlst_),
00065 initDisjPercentage_ (src.initDisjPercentage_),
00066 initDisjNumber_ (src.initDisjNumber_),
00067 depthLevelling_ (src.depthLevelling_),
00068 depthStopSeparate_ (src.depthStopSeparate_),
00069 activeRows_ (src.activeRows_),
00070 activeCols_ (src.activeCols_),
00071 addPreviousCut_ (src.addPreviousCut_),
00072 cpuTime_ (src.cpuTime_) {}
00073
00074
00075
00077 CouenneDisjCuts::~CouenneDisjCuts ()
00078 {if (septime_ > 1e-9) jnlst_ -> Printf (J_ERROR, J_DISJCUTS, "Disjunctive cuts: total time %g\n", septime_);}
00079
00080
00082 void CouenneDisjCuts::registerOptions (Ipopt::SmartPtr <Bonmin::RegisteredOptions> roptions) {
00083
00084 roptions -> AddLowerBoundedIntegerOption
00085 ("minlp_disj_cuts",
00086 "The frequency (in terms of nodes) at which Couenne disjunctive cuts are generated.",
00087 -99, 0,
00088 "A frequency of 0 (default) means these cuts are never generated. "
00089 "Any positive number n instructs Couenne to generate them at every n nodes of the B&B tree. "
00090 "A negative number -n means that generation should be attempted at the root node, and if successful it can be repeated at every n nodes, otherwise it is stopped altogether."
00091 );
00092
00093 roptions -> AddLowerBoundedIntegerOption
00094 ("disj_init_number",
00095 "Maximum number of disjunction to consider at each iteration.",
00096 -1, 10, "-1 means no limit.");
00097
00098 roptions -> AddBoundedNumberOption
00099 ("disj_init_perc",
00100 "The maximum fraction of all disjunctions currently violated by the problem to consider for generating disjunctions.",
00101 0., false,
00102 1., false,
00103 0.5, "");
00104
00105 roptions -> AddLowerBoundedIntegerOption
00106 ("disj_depth_level",
00107 "Depth of the B&B tree when to start decreasing the number of objects that generate disjunctions.",
00108 -1, 5, "This has a similar behavior as log_num_obbt_per_level. "
00109 "A value of -1 means that generation can be done at all nodes.");
00110
00111 roptions -> AddLowerBoundedIntegerOption
00112 ("disj_depth_stop",
00113 "Depth of the B&B tree where separation of disjunctive cuts is stopped.",
00114 -1, 20, "A value of -1 means that generation can be done at all nodes");
00115
00116 roptions -> AddStringOption2
00117 ("disj_active_rows",
00118 "Only include violated linear inequalities in the CGLP.",
00119 "no",
00120 "yes", "",
00121 "no", "",
00122 "This reduces the size of the CGLP, but may produce less efficient cuts.");
00123
00124 roptions -> AddStringOption2
00125 ("disj_active_cols",
00126 "Only include violated variable bounds in the Cut Generating LP (CGLP).",
00127 "no",
00128 "yes", "",
00129 "no", "",
00130 "This reduces the size of the CGLP, but may produce less efficient cuts."
00131 );
00132
00133 roptions -> AddStringOption2
00134 ("disj_cumulative",
00135 "Add previous disjunctive cut to current CGLP.",
00136 "no",
00137 "yes", "",
00138 "no", "",
00139 "When generating disjunctive cuts on a set of disjunctions 1, 2, ..., k, introduce the cut relative to the previous disjunction i-1 in the CGLP used for disjunction i. "
00140 "Notice that, although this makes the cut generated more efficient, it increases the rank of the disjunctive cut generated."
00141 );
00142 }