12 #include "OsiSolverInterface.hpp"
14 #include "CbcBranchActual.hpp"
15 #include "CbcModel.hpp"
33 return (one -> priority_ <
37 using namespace Couenne;
52 OsiChooseVariable (si),
59 OsiChooseVariable (source),
60 problem_ (source.problem_),
61 jnlst_ (source.jnlst_) {}
77 static bool firstCall =
true;
87 jnlst_ -> Printf (Ipopt::J_ITERSUMMARY,
J_BRANCHING,
"----------------- setup list\n");
89 printf (
"----------------- setup list\n");
90 for (
int i=0; i<
problem_ -> domain () -> current () -> Dimension (); i++)
91 if (
problem_ -> Var (i) -> Multiplicity () > 0) {
92 printf (
"%4d %20.4g [%20.4g %20.4g]", i, info -> solution_ [i], info -> lower_ [i], info -> upper_ [i]);
94 printf (
" expr. %20.4g [%+e] ", (*(
problem_ -> Var (i) -> Image ())) (), (*(
problem_ -> Var (i) -> Image ())) () - info -> solution_ [i]);
95 problem_ -> Var (i) -> Image () -> print ();
112 delete [] goodSolution_;
115 numberStrongIterations_ = 0;
116 numberStrongFixed_ = 0;
117 goodSolution_ = NULL;
118 goodObjectiveValue_ = COIN_DBL_MAX;
122 numberUnsatisfied_=0;
132 int numberObjects = solver_ -> numberObjects();
134 assert (numberObjects);
136 OsiObject **
object = info -> solver_ -> objects ();
139 bool feasible =
true;
152 #define NEW_SETUPLIST
158 std::vector <struct objPri *> listPri;
160 for (
int i=0; i<numberObjects; i++) {
164 singleton ->
priority_ =
object [i] -> priority ();
166 listPri.push_back (singleton);
174 std::sort (listPri.begin (), listPri.end (),
compPri);
180 int minPriority = -1;
182 double maxInfeas = 0.;
184 for (
int i=0; i<numberObjects; ++i) {
190 if ((minPriority >= 0) &&
191 (priority > minPriority))
195 double infeas =
object [currIndex] -> checkInfeasibility (info);
199 if (((minPriority < 0) || (priority == minPriority)) &&
200 (infeas > maxInfeas)) {
205 minPriority = priority;
209 ++numberUnsatisfied_;
211 if (infeas == COIN_DBL_MAX) {
218 list_ [0] = currIndex;
219 useful_ [0] = infeas;
231 for (std::vector <struct objPri *>::iterator i=listPri.begin (); i != listPri.end (); ++i)
236 int maximumStrong = numberStrong_ ? CoinMin (numberStrong_, numberObjects) : 1;
242 bestPriority = COIN_INT_MAX,
244 putOther = numberObjects;
248 for (
int i=0; i < maximumStrong; i++) {
259 for (
int i=0; i<numberObjects; i++) {
263 double value =
object [i] -> checkInfeasibility (info);
267 numberUnsatisfied_++;
269 if (value == COIN_DBL_MAX) {
274 int priorityLevel =
object [i] -> priority ();
277 if (priorityLevel < bestPriority) {
279 for (
int j=0;
j<maximumStrong;
j++) {
281 if (list_ [
j] >= 0) {
283 int iObject = list_[
j];
287 list_ [--putOther] = iObject;
291 bestPriority = priorityLevel;
295 if ((priorityLevel == bestPriority)
300 int iObject = list_ [checkIndex];
302 list_ [--putOther] = iObject;
305 list_ [checkIndex] = i;
306 useful_ [checkIndex] = value;
310 for (
int j=0;
j<maximumStrong;
j++) {
312 if (useful_[
j]<check) {
322 }
else list_ [--putOther] = i;
332 #ifndef NEW_SETUPLIST
333 for (
int i=0;i<maximumStrong;i++) {
335 list_[numberOnList_]=list_[i];
336 useful_[numberOnList_++]=-useful_[i];
341 CoinSort_2(useful_,useful_+numberOnList_,list_);
343 int i = numberOnList_;
344 for (;putOther<numberObjects;putOther++)
345 list_[i++]=list_[putOther];
346 assert (i==numberUnsatisfied_);
353 numberUnsatisfied_ = -1;
356 retval = numberUnsatisfied_;
367 jnlst_ -> Printf (Ipopt::J_ITERSUMMARY,
J_BRANCHING,
"----------------- setup list done, %d objects\n", retval);
400 const double * solution,
402 const OsiObject ** objects) {
414 int indobj =
problem_ -> Obj (0) -> Body () -> Index ();
415 double obj = indobj >= 0 ? solution [indobj] :
problem_ -> Obj (0) -> Body () -> Value ();
416 return problem_ -> checkNLP (solution, obj);
424 roptions -> AddStringOption2
426 "Use Special Ordered Sets (SOS) as indicated in the MINLP model",
431 roptions -> AddStringOption2
433 "Apply bound tightening before branching",
437 "After applying a branching rule and before re-solving the subproblem, apply Bound Tightening.");
439 roptions -> AddStringOption2
441 "Apply convexification cuts before branching (for now only within strong branching)",
445 "After applying a branching rule and before resolving the subproblem, generate a round of linearization cuts with the new bounds enforced by the rule."
448 roptions -> AddStringOption6
450 "Chooses branching point selection strategy",
452 "lp-clamped",
"LP point clamped in [k,1-k] of the bound intervals (k defined by lp_clamp)",
453 "lp-central",
"LP point if within [k,1-k] of the bound intervals, middle point otherwise"
454 "(k defined by branch_lp_clamp)",
455 "balanced",
"minimizes max distance from curve to convexification",
456 "min-area",
"minimizes total area of the two convexifications",
457 "mid-point",
"convex combination of current point and mid point",
458 "no-branch",
"do not branch, return null infeasibility; for testing purposes only",
461 std::string br_ops [] = {
"prod",
"div",
"exp",
"log",
"trig",
462 "pow",
"negpow",
"sqr",
"cube",
""};
464 for (
int i=0; br_ops [i] !=
""; i++) {
466 char optname [40], optname2 [40], description [90];
467 sprintf (optname,
"branch_pt_select_%s", br_ops [i].c_str ());
468 sprintf (optname2,
"branch_lp_clamp_%s", br_ops [i].c_str ());
469 sprintf (description,
"Chooses branching point selection strategy for operator %s.",
470 br_ops [i].c_str ());
472 roptions -> AddStringOption7
476 "common",
"use strategy defined for generic operators",
477 "lp-clamped",
"LP point clamped in [k,1-k] of the bound intervals "
478 "(k defined by lp_clamp_${this operator}$)",
479 "lp-central",
"LP point if within [k,1-k] of the bound intervals, middle point otherwise"
480 "(k defined by branch_lp_clamp_${this operator}$)",
481 "balanced",
"minimizes max distance from curve to convexification",
482 "min-area",
"minimizes total area of the two convexifications",
483 "mid-point",
"convex combination of current point and mid point",
484 "no-branch",
"do not branch, return null infeasibility; for testing purposes only",
487 roptions -> AddBoundedNumberOption
489 "Defines safe interval percentage [0,0.5] for using LP point as a branching point.",
495 roptions -> AddBoundedNumberOption
496 (
"branch_midpoint_alpha",
497 "Defines convex combination of mid point and current LP point: "
498 "b = alpha x_lp + (1-alpha) (lb+ub)/2.",
503 roptions -> AddBoundedNumberOption
505 "Defines safe interval percentage for using LP point as a branching point.",
513 roptions -> AddLowerBoundedIntegerOption
514 (
"cont_var_priority",
515 "Priority of continuous variable branching",
517 "When branching, this is compared to the priority of integer variables, whose priority is given by int_var_priority, and SOS, whose priority is 10. "
518 "Higher values mean smaller priority."
521 roptions -> AddLowerBoundedIntegerOption
523 "Priority of integer variable branching",
525 "When branching, this is compared to the priority of continuous variables, whose priority is given by cont_var_priority, and SOS, whose priority is 10. "
526 "Higher values mean smaller priority."
529 roptions -> AddStringOption2
530 (
"red_cost_branching",
531 "Apply Reduced Cost Branching (instead of the Violation Transfer) -- MUST have vt_obj enabled",
533 "no",
"Use Violation Transfer with $\\sum |\\pi_i a_{ij}|$",
534 "yes",
"Use Reduced cost branching with $|\\sum \\pi_i a_{ij}|$");
536 roptions -> AddStringOption2
537 (
"orbital_branching",
538 "detect symmetries and apply orbital branching",
543 roptions -> AddLowerBoundedIntegerOption
544 (
"orbital_branching_depth",
545 "Maximum depth at which the symmetry group is computed",
547 "Select -1 if you want to compute the symmetry group at all nodes");
561 for (; currObj < nco; ++currObj)
563 if ((NULL != dynamic_cast <CbcSimpleInteger *> (objects [currObj])) ||
564 (NULL != dynamic_cast <OsiSimpleInteger *> (objects [currObj]))) {
567 delete objects [currObj];
568 objects [currObj] = NULL;
573 for (nRealObj = 0, currObj = -1; nRealObj < nco; ++nRealObj)
575 if (NULL == objects [nRealObj]) {
578 currObj = nRealObj + 1;
580 while ((currObj < nco) &&
581 (NULL == objects [currObj]))
590 objects [currObj] = NULL;
CouenneProblem * problem_
Pointer to the associated MINLP problem.
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real fint fint fint fint * info
JnlstPtr jnlst_
journalist for detailed debug information
bool checkNLP2(const double *solution, const double obj, const bool careAboutObj, const bool stopAtFirstViol, const bool checkAll, const double precision) const
Return true if either solution or recomputed_solution obtained using getAuxs() from the original vari...
const Ipopt::EJournalCategory J_BRANCHING(Ipopt::J_USER1)
const CouNumber default_alpha
CouenneChooseVariable & operator=(const CouenneChooseVariable &)
Assignment operator.
int gutsofEIO(OsiObject **objects, int nco)
virtual int setupList(OsiBranchingInformation *, bool)
Sets up strong list and clears all if initialize is true.
Class for MINLP problems with symbolic information.
virtual bool feasibleSolution(const OsiBranchingInformation *info, const double *solution, int numberObjects, const OsiObject **objects)
Returns true if solution looks feasible against given objects.
bool compPri(struct objPri *one, struct objPri *two)
Choose a variable for branching.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Add list of options to be read from file.
void eliminateIntegerObjects(OsiSolverInterface *model)
CouenneChooseVariable()
Default Constructor.