00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "CglCutGenerator.hpp"
00013
00014 #include "CouenneProblem.hpp"
00015 #include "CouenneCutGenerator.hpp"
00016 #include "CouenneChooseStrong.hpp"
00017 #include "CouenneChooseVariable.hpp"
00018
00019
00021 CouenneCutGenerator::CouenneCutGenerator (Bonmin::OsiTMINLPInterface *nlp,
00022 Bonmin::BabSetupBase *base,
00023 CouenneProblem *problem,
00024 struct ASL *asl):
00025
00026 CglCutGenerator (),
00027
00028 firstcall_ (true),
00029 problem_ (problem),
00030 nrootcuts_ (0),
00031 ntotalcuts_ (0),
00032 septime_ (0),
00033 objValue_ (- DBL_MAX),
00034 nlp_ (nlp),
00035 BabPtr_ (NULL),
00036 infeasNode_ (false),
00037 jnlst_ (base ? base -> journalist () : NULL),
00038 rootTime_ (-1.) {
00039
00040 if (base) {
00041
00042 base -> options () -> GetIntegerValue ("convexification_points", nSamples_, "couenne.");
00043
00044 std::string s;
00045
00046 base -> options () -> GetStringValue ("convexification_type", s, "couenne.");
00047 if (s == "current-point-only") convtype_ = CURRENT_ONLY;
00048 else if (s == "uniform-grid") convtype_ = UNIFORM_GRID;
00049 else convtype_ = AROUND_CURPOINT;
00050
00051 base -> options () -> GetStringValue ("violated_cuts_only", s, "couenne.");
00052 addviolated_ = (s == "yes");
00053
00054 base -> options () -> GetStringValue ("check_lp", s, "couenne.");
00055 check_lp_ = (s == "yes");
00056
00057 base -> options () -> GetStringValue ("enable_lp_implied_bounds", s, "couenne.");
00058 enable_lp_implied_bounds_ = (s == "yes");
00059
00060 } else {
00061
00062 nSamples_ = 4;
00063 convtype_ = CURRENT_ONLY;
00064 addviolated_ = true;
00065 check_lp_ = false;
00066 enable_lp_implied_bounds_ = false;
00067 }
00068
00069
00070
00071 }
00072
00073
00075 CouenneCutGenerator::~CouenneCutGenerator ()
00076 {}
00077
00078
00080 CouenneCutGenerator::CouenneCutGenerator (const CouenneCutGenerator &src):
00081
00082 CglCutGenerator (src),
00083
00084 firstcall_ (src. firstcall_),
00085 addviolated_ (src. addviolated_),
00086 convtype_ (src. convtype_),
00087 nSamples_ (src. nSamples_),
00088 problem_ (src. problem_),
00089 nrootcuts_ (src. nrootcuts_),
00090 ntotalcuts_ (src. ntotalcuts_),
00091 septime_ (src. septime_),
00092 objValue_ (src. objValue_),
00093 nlp_ (src. nlp_),
00094 BabPtr_ (src. BabPtr_),
00095 infeasNode_ (src. infeasNode_),
00096 jnlst_ (src. jnlst_),
00097 rootTime_ (src. rootTime_),
00098 check_lp_ (src. check_lp_),
00099 enable_lp_implied_bounds_ (src.enable_lp_implied_bounds_)
00100 {}
00101
00102
00103 #define MAX_SLOPE 1e3
00104
00106 int CouenneCutGenerator::addSegment (OsiCuts &cs, int wi, int xi,
00107 CouNumber x1, CouNumber y1,
00108 CouNumber x2, CouNumber y2, int sign) const {
00109
00110 if (fabs (x2-x1) < COUENNE_EPS) {
00111 if (fabs (y2-y1) > MAX_SLOPE * COUENNE_EPS)
00112 jnlst_->Printf(J_WARNING, J_CONVEXIFYING,
00113 "warning, discontinuity of %e over an interval of %e\n", y2-y1, x2-x1);
00114 else return createCut (cs, y2, (int) 0, wi, 1.);
00115 }
00116
00117 CouNumber dx = x2-x1, dy = y2-y1;
00118
00119
00120 return createCut (cs, y1*dx - dy*x1, (dx>0) ? sign : -sign, wi, dx, xi, -dy);
00121 }
00122
00123
00125 int CouenneCutGenerator::addTangent (OsiCuts &cs, int wi, int xi,
00126 CouNumber x, CouNumber w,
00127 CouNumber slope, int sign) const
00128 {return createCut (cs, w - slope * x, sign, wi, 1., xi, - slope);}
00129
00130
00132 int CouenneCutGenerator::getnvars () const
00133 {return problem_ -> nVars ();}
00134
00135
00137 void CouenneCutGenerator::registerOptions (Ipopt::SmartPtr <Bonmin::RegisteredOptions> roptions) {
00138
00139 roptions -> SetRegisteringCategory ("Couenne options", Bonmin::RegisteredOptions::CouenneCategory);
00140
00141 roptions -> AddLowerBoundedIntegerOption
00142 ("convexification_cuts",
00143 "Specify the frequency (in terms of nodes) at which couenne ecp cuts are generated.",
00144 -99,1,
00145 "A frequency of 0 amounts to never solve the NLP relaxation.");
00146
00147 roptions -> AddStringOption2
00148 ("check_lp",
00149 "Check all LPs through an independent call to OsiClpSolverInterface::initialSolve()",
00150 "no",
00151 "no","",
00152 "yes","");
00153
00154 roptions -> AddStringOption2
00155 ("local_optimization_heuristic",
00156 "Do we search for local solutions of NLP's",
00157 "yes",
00158 "no","",
00159 "yes","",
00160 "If enabled, a heuristic based on Ipopt is used to find feasible solutions for the problem. "
00161 "It is highly recommended that this option is left enabled, as it would be difficult to find feasible solutions otherwise.");
00162
00163 roptions -> AddLowerBoundedIntegerOption
00164 ("log_num_local_optimization_per_level",
00165 "Specify the logarithm of the number of local optimizations to perform"
00166 " on average for each level of given depth of the tree.",
00167 -1,
00168 2, "Solve as many nlp's at the nodes for each level of the tree. "
00169 "Nodes are randomly selected. If for a "
00170 "given level there are less nodes than this number nlp are solved for every nodes. "
00171 "For example if parameter is 8, nlp's are solved for all node until level 8, "
00172 "then for half the node at level 9, 1/4 at level 10.... "
00173 "Value -1 specify to perform at all nodes.");
00174
00175 roptions -> AddStringOption3
00176 ("convexification_type",
00177 "Determines in which point the linear over/under-estimator are generated",
00178 "current-point-only",
00179 "current-point-only","Only at current optimum of relaxation",
00180 "uniform-grid","Points chosen in a uniform grid between the bounds of the problem",
00181 "around-current-point","At points around current optimum of relaxation",
00182 "For the lower envelopes of convex functions, this is the number of points where a supporting hyperplane is generated. "
00183 "This only holds for the initial linearization, as all other linearizations only add at most one cut per expression."
00184 );
00185
00186 roptions -> AddLowerBoundedIntegerOption
00187 ("convexification_points",
00188 "Specify the number of points at which to convexify when convexification type "
00189 "is uniform-grid or around-current-point.",
00190 0,4,
00191 "");
00192
00193 roptions -> AddStringOption2
00194 ("violated_cuts_only",
00195 "Yes if only violated convexification cuts should be added",
00196 "yes",
00197 "no","",
00198 "yes","");
00199
00200 roptions -> AddStringOption2
00201 ("enable_lp_implied_bounds",
00202 "Enable OsiSolverInterface::tightenBounds () -- warning: it has caused "
00203 "some trouble to Couenne",
00204 "no",
00205 "no","",
00206 "yes","");
00207
00208 CouenneProblem :: registerOptions (roptions);
00209 CouenneChooseStrong :: registerOptions (roptions);
00210 CouenneChooseVariable :: registerOptions (roptions);
00211 }