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