00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "CouenneChooseVariable.hpp"
00013 #include "CouenneProblem.hpp"
00014
00015
00017 CouenneChooseVariable::CouenneChooseVariable ():
00018 OsiChooseVariable (),
00019 problem_ (NULL) {}
00020
00021
00023 CouenneChooseVariable::CouenneChooseVariable (const OsiSolverInterface *si,
00024 CouenneProblem *p,
00025 JnlstPtr jnlst):
00026 OsiChooseVariable (si),
00027 problem_ (p),
00028 jnlst_ (jnlst) {}
00029
00030
00032 CouenneChooseVariable::CouenneChooseVariable (const CouenneChooseVariable &source):
00033 OsiChooseVariable (source),
00034 problem_ (source.problem_),
00035 jnlst_ (source.jnlst_) {}
00036
00037
00039 CouenneChooseVariable & CouenneChooseVariable::operator= (const CouenneChooseVariable& rhs) {
00040 problem_ = rhs.problem_;
00041 jnlst_ = rhs.jnlst_;
00042 return *this;
00043 }
00044
00045
00049 int CouenneChooseVariable::setupList (OsiBranchingInformation *info, bool initialize) {
00050
00051 problem_ -> domain () -> push
00052 (problem_ -> nVars (),
00053 info -> solution_,
00054 info -> lower_,
00055 info -> upper_);
00056
00057 jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING, "----------------- setup list\n");
00058
00059 if (jnlst_ -> ProduceOutput (J_DETAILED, J_BRANCHING)) {
00060
00061 printf ("----------------- setup list\n");
00062
00063 for (int i=0; i<problem_ -> domain () -> current () -> Dimension (); i++)
00064
00065 if (problem_ -> Var (i) -> Multiplicity () > 0) {
00066 printf ("%4d %20.4g [%20.4g %20.4g]", i,
00067 info -> solution_ [i],
00068 info -> lower_ [i],
00069 info -> upper_ [i]);
00070
00071 if (problem_ -> Var (i) -> Type () == AUX) {
00072 printf (" expr. %20.4g [%+e] ",
00073 (*(problem_ -> Var (i) -> Image ())) (),
00074 (*(problem_ -> Var (i) -> Image ())) () - info -> solution_ [i]);
00075 problem_ -> Var (i) -> Image () -> print ();
00076 }
00077
00078 printf ("\n");
00079 }
00080 }
00081
00082
00083 int retval = (solver_ -> numberObjects ()) ?
00084 OsiChooseVariable::setupList (info, initialize) : 0;
00085
00086 problem_ -> domain () -> pop ();
00087
00088 jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING, "----------------- setup list done, %d objects\n",
00089 retval);
00090
00091 return retval;
00092 }
00093
00094
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 bool CouenneChooseVariable::feasibleSolution (const OsiBranchingInformation * info,
00117 const double * solution,
00118 int numberObjects,
00119 const OsiObject ** objects) {
00120
00121 double obj = solution [problem_ -> Obj (0) -> Body () -> Index ()];
00122 return problem_ -> checkNLP (solution, obj);
00123 }
00124
00125
00127 void CouenneChooseVariable::registerOptions (Ipopt::SmartPtr <Bonmin::RegisteredOptions> roptions) {
00128
00129 roptions -> AddStringOption2
00130 ("enable_sos",
00131 "Use Special Ordered Sets (SOS) as indicated in the MINLP model",
00132 "no",
00133 "no","",
00134 "yes","");
00135
00136 roptions -> AddStringOption2
00137 ("branch_fbbt",
00138 "Apply bound tightening before branching",
00139 "yes",
00140 "no","",
00141 "yes","",
00142 "After applying a branching rule and before re-solving the subproblem, apply Bound Tightening.");
00143
00144 roptions -> AddStringOption2
00145 ("branch_conv_cuts",
00146 "Apply convexification cuts before branching (for now only within strong branching)",
00147 "yes",
00148 "no","",
00149 "yes","",
00150 "After applying a branching rule and before resolving the subproblem, generate a round of linearization cuts with the new bounds enforced by the rule."
00151 );
00152
00153 roptions -> AddStringOption6
00154 ("branch_pt_select",
00155 "Chooses branching point selection strategy",
00156 "mid-point",
00157 "lp-clamped", "LP point clamped in [k,1-k] of the bound intervals (k defined by lp_clamp)",
00158 "lp-central", "LP point if within [k,1-k] of the bound intervals, middle point otherwise"
00159 "(k defined by branch_lp_clamp)",
00160 "balanced", "minimizes max distance from curve to convexification",
00161 "min-area", "minimizes total area of the two convexifications",
00162 "mid-point", "convex combination of current point and mid point",
00163 "no-branch", "do not branch, return null infeasibility; for testing purposes only",
00164 "");
00165
00166 std::string br_ops [] = {"prod", "div", "exp", "log", "trig",
00167 "pow", "negpow", "sqr", "cube", ""};
00168
00169 for (int i=0; br_ops [i] != ""; i++) {
00170
00171 char optname [40], optname2 [40], description [90];
00172 sprintf (optname, "branch_pt_select_%s", br_ops [i].c_str ());
00173 sprintf (optname2, "branch_lp_clamp_%s", br_ops [i].c_str ());
00174 sprintf (description, "Chooses branching point selection strategy for operator %s",
00175 br_ops [i].c_str ());
00176
00177 roptions -> AddStringOption7
00178 (optname,
00179 description,
00180 "common",
00181 "common", "use strategy defined for generic operators",
00182 "lp-clamped", "LP point clamped in [k,1-k] of the bound intervals "
00183 "(k defined by lp_clamp_${this operator}$)",
00184 "lp-central", "LP point if within [k,1-k] of the bound intervals, middle point otherwise"
00185 "(k defined by branch_lp_clamp_${this operator}$)",
00186 "balanced", "minimizes max distance from curve to convexification",
00187 "min-area", "minimizes total area of the two convexifications",
00188 "mid-point", "convex combination of current point and mid point",
00189 "no-branch", "do not branch, return null infeasibility; for testing purposes only",
00190 "");
00191
00192 roptions -> AddBoundedNumberOption
00193 (optname2,
00194 "Defines safe interval percentage [0,0.5] for using LP point as a branching point",
00195 0.,false,
00196 0.5,false,
00197 0.2,
00198 "Default value is 0.2.");
00199 }
00200
00201 roptions -> AddBoundedNumberOption
00202 ("branch_midpoint_alpha",
00203 "Defines convex combination of mid point and current LP point: "
00204 "b = alpha x_lp + (1-alpha) (lb+ub)/2.",
00205 0.,false,
00206 1.,false,
00207 0.25,
00208 "Default value is 0.25.");
00209
00210 roptions -> AddBoundedNumberOption
00211 ("branch_lp_clamp",
00212 "Defines safe interval percentage for using LP point as a branching point",
00213 0.,false,
00214 1.,false,
00215 0.2,
00216 "Default value is 0.2.");
00217
00218 roptions -> AddLowerBoundedIntegerOption
00219 ("cont_var_priority",
00220 "Priority of continuous variable branching",
00221 1, 2000,
00222 "When branching, this is compared to the priority of integer variables, whose priority is fixed to 1000, and SOS, whose priority is 10. "
00223 "Higher values mean smaller priority, so if this parameter is set to 1001 or higher, if a branch-and-bound node has at least one integer variable whose value is fractional, then branching will be performed on that variable."
00224 );
00225
00226 roptions -> AddStringOption2
00227 ("red_cost_branching",
00228 "Apply Reduced Cost Branching (instead of the Violation Transfer) -- MUST have vt_obj enabled",
00229 "no",
00230 "no", "Use Violation Transfer with $\\sum |\\pi_i a_{ij}|$",
00231 "yes","Use Reduced cost branching with $|\\sum \\pi_i a_{ij}|$");
00232
00233 roptions -> AddStringOption2 (
00234 "orbital_branching",
00235 "detect symmetries and apply orbital branching",
00236 "no",
00237 "yes", "",
00238 "no", "");
00239 }