15 #include "CoinHelperFunctions.hpp"
16 #include "CoinTime.hpp"
32 using namespace Couenne;
34 #define MAX_FBBT_ITER 3
39 jnlst_ = base -> journalist ();
60 for (
int i=0; i < nvars; i++) {
68 Lb (indvar) = - (
Ub (indvar) = COIN_DBL_MAX);
75 for (std::vector <CouenneConstraint *>::const_iterator con =
constraints_.begin ();
79 lb = (*((*con) ->
Lb ())) (),
80 ub = (*((*con) ->
Ub ())) ();
82 int index = (*con) -> Body () -> Index ();
93 Jnlst () -> Printf (Ipopt::J_MOREMATRIX,
J_PROBLEM,
"InitAux -- assigning bounds\n");
95 for (
int j=0, i=
nVars (); i--;
j++) {
100 if (
variables_ [ord] -> Multiplicity () == 0) {
101 Lb (ord) = - (
Ub (ord) = COIN_DBL_MAX);
109 if (var -> Type () ==
AUX) {
112 "w_%04d [%10g,%10g] ", ord,
Lb (ord),
Ub (ord));
116 var -> Image () -> getBounds (l, u);
123 " ( --> w_%04d [%10g,%10g] ) vs [%10g %10g]",
124 ord, l, u,
Lb (ord),
Ub (ord));
133 bool integer = var -> isDefinedInteger ();
140 double image = (*(var -> Image ())) ();
149 X (ord) = CoinMax (
Lb (ord), CoinMin (
Ub (ord),
X (ord)));
152 " --> [%10g,%10g] (%g)\n",
Lb (ord),
Ub (ord),
X (ord));
170 for (
int i = 0; i <
nVars (); ++i) {
182 for (
int j=0, i=nVars (); i--;
j++) {
187 if (var -> Multiplicity () > 0) {
191 if (var -> Type () ==
AUX)
192 var -> Image () -> getBounds (l,u);
198 if (var -> Type () ==
AUX) {
202 bool isInt = var -> isDefinedInteger ();
214 x = (*(var -> Image ())) ();
229 }
else X (index) = 0.;
250 switch (body -> code ()) {
253 obj [body -> Index ()] = 1;
260 obj [arglist [0] -> Index ()] = 1;
261 obj [arglist [1] -> Index ()] = -1;
276 for (
int n = (
int) lcoe.size (), i=0;
n--; i++)
278 obj [lcoe [i]. first -> Index ()] = lcoe [i]. second;
289 for (
int i = body -> nArgs (); i--;)
290 switch ((arglist [i]) -> code ()) {
296 obj [arglist [i] -> Index ()] = 1;
301 expression **mulArgList = arglist [i] -> ArgList ();
302 int index = mulArgList [0] -> Index ();
304 if (index >= 0) obj [index] = mulArgList [1] -> Value ();
305 else obj [mulArgList [1] -> Index ()] = mulArgList [0] -> Value ();
310 "Couenne: invalid element of sum\nAborting\n");
319 "Couenne: warning, objective function not recognized\n");
331 int indobj =
objectives_ [0] -> Body () -> Index ();
338 Jnlst () -> Printf (Ipopt::J_ERROR,
J_COUENNE,
"Couenne: new cutoff value %.10e (%g seconds)\n", cutoff, CoinCpuTime ());
350 int indobj =
objectives_ [0] -> Body () -> Index ();
371 int indobj =
objectives_ [0] -> Body () -> Index ();
386 if (cutoff <
Ub (indobj))
387 Ub (indobj) = cutoff;
395 for (std::vector <exprVar *>::iterator i =
variables_.begin ();
398 if ((*i) -> Multiplicity () <= 0)
403 if ((*i) -> Type () ==
AUX)
404 (*i) -> Image () ->
realign (
this);
408 for (std::vector <CouenneObjective *>::iterator i =
objectives_.begin ();
410 (*i) -> Body () ->
realign (
this);
414 for (std::vector <CouenneConstraint *>::iterator i =
constraints_.begin ();
416 (*i) -> Body () ->
realign (
this);
425 roptions -> AddNumberOption
429 "Default value is infinity.");
431 roptions -> AddNumberOption
433 "Window around known optimum",
435 "Default value is infinity.");
437 roptions -> AddStringOption2
439 "Use semiauxiliaries, i.e. auxiliaries defined as w >= f(x) rather than w := f(x))",
441 "no",
"Only use auxiliaries assigned with \"=\" ",
442 "yes",
"Use auxiliaries defined by w <= f(x), w >= f(x), and w = f(x)"
445 roptions -> AddStringOption2
447 "Use constraints-defined auxiliaries, i.e. auxiliaries w = f(x) defined by original constraints f(x) - w = 0",
453 roptions -> AddStringOption2
455 "Reduced cost bound tightening",
459 "This bound reduction technique uses the reduced costs of the LP in order to infer better variable bounds.");
461 roptions -> AddStringOption2
463 "Use quadratic expressions and related exprQuad class",
465 "no",
"Use an auxiliary for each bilinear term",
466 "yes",
"Create only one auxiliary for a quadratic expression",
467 "If enabled, then quadratic forms are not reformulated and therefore decomposed as a sum of auxiliary variables, each associated with a bilinear term, but rather taken as a whole expression. "
468 "Envelopes for these expressions are generated through alpha-convexification."
471 roptions -> AddStringOption2
473 "Optimality-based (expensive) bound tightening (OBBT)",
477 "This is another bound reduction technique aiming at reducing the solution set by looking at the initial LP relaxation. "
478 "This technique is computationally expensive, and should be used only when necessary."
481 roptions -> AddLowerBoundedIntegerOption
482 (
"log_num_obbt_per_level",
483 "Specify the frequency (in terms of nodes) for optimality-based bound tightening.",
486 If -1, apply at every node (expensive!). \
487 If 0, apply at root node only. \
488 If k>=0, apply with probability 2^(k - level), level being the current depth of the B&B tree.");
490 roptions -> AddLowerBoundedIntegerOption
492 "Number of FBBT iterations before stopping even with tightened bounds.",
494 "Set to -1 to impose no upper limit");
496 roptions -> AddStringOption2
498 "Aggressive feasibility-based bound tightening (to use with NLP points)",
502 "Aggressive FBBT is a version of probing that also allows to reduce the solution set, although it is not as quick as FBBT. "
503 "It can be applied up to a certain depth of the B&B tree -- see ``log_num_abt_per_level''. "
504 "In general, this option is useful but can be switched off if a problem is too large and seems not to benefit from it."
507 roptions -> AddLowerBoundedIntegerOption
508 (
"log_num_abt_per_level",
509 "Specify the frequency (in terms of nodes) for aggressive bound tightening.",
512 If -1, apply at every node (expensive!). \
513 If 0, apply at root node only. \
514 If k>=0, apply with probability 2^(k - level), level being the current depth of the B&B tree.");
516 roptions -> AddNumberOption
518 "Artificial lower bound",
520 "Default value is -COIN_DBL_MAX.");
522 roptions -> AddStringOption3
524 "type of branching object for variable selection",
526 "vt_obj",
"use Violation Transfer from Tawarmalani and Sahinidis",
527 "var_obj",
"use one object for each variable",
528 "expr_obj",
"use one object for each nonlinear expression");
530 roptions -> AddStringOption2
532 "Eliminate redundant variables, which appear in the problem as x_k = x_h",
534 "no",
"Keep redundant variables, making the problem a bit larger",
535 "yes",
"Eliminate redundant variables (the problem will be equivalent, only smaller)");
537 roptions -> AddStringOption4
538 (
"quadrilinear_decomp",
539 "type of decomposition for quadrilinear terms (see work by Cafieri, Lee, Liberti)",
541 "rAI",
"Recursive decomposition in bilinear terms (as in Ryoo and Sahinidis): x5 = ((x1 x2) x3) x4)",
542 "tri+bi",
"Trilinear and bilinear term: x5 = (x1 (x2 x3 x4))",
543 "bi+tri",
"Bilinear, THEN trilinear term: x5 = ((x1 x2) x3 x4))",
544 "hier-bi",
"Hierarchical decomposition: x5 = ((x1 x2) (x3 x4))");
void realign()
clear all spurious variables pointers not referring to the variables_ vector
GlobalCutOff * pcutoff_
Pointer to a global cutoff object.
int nVars() const
Total number of variables.
class Group, with constant, linear and nonlinear terms:
const CouNumber SafeDelta
CouNumber & ub(register int index)
current upper bound
std::vector< CouenneObjective * > objectives_
Objectives.
CouNumber & lb(register int index)
current lower bound
Option category for Couenne.
void setCutOff(CouNumber cutoff, const CouNumber *sol=NULL) const
Set cutoff.
std::vector< expression * > commonexprs_
AMPL's common expressions (read from AMPL through structures cexps and cexps1)
CouNumber getCutOff() const
Get cutoff.
void setBase(Bonmin::BabSetupBase *base)
save CouenneBase
void fint fint fint real fint real real real real real real real real real * e
A class to have all elements necessary to setup a branch-and-bound.
void restoreUnusedOriginals(CouNumber *=NULL) const
Some originals may be unused due to their zero multiplicity (that happens when they are duplicates)...
void getAuxs(CouNumber *) const
Get auxiliary variables from original variables.
int ndefined_
Number of "defined variables" (aka "common expressions")
ConstJnlstPtr Jnlst() const
Provide Journalist.
Bonmin::BabSetupBase * bonBase_
options
std::vector< CouenneConstraint * > constraints_
Constraints.
const CouNumber SafeCutoff
void pop()
restore previous point
void fint fint fint fint fint fint fint fint fint fint real real real real real real real real * s
exprVar * Var(int i) const
Return pointer to i-th variable.
std::vector< exprVar * > variables_
Variables (original, auxiliary, and defined)
Domain domain_
current point and bounds;
int * numbering_
numbering of variables.
CouNumber * Ub() const
Return vector of upper bounds.
void installCutOff() const
Make cutoff known to the problem.
void initAuxs() const
Initialize auxiliary variables and their bounds from original variables.
std::vector< std::pair< exprVar *, CouNumber > > lincoeff
double CouNumber
main number type in Couenne
int nOrigVars_
Number of original variables.
void resetCutOff(CouNumber value=COUENNE_INFINITY) const
Reset cutoff.
CouNumber * X() const
Return vector of variables.
void push(int dim, CouNumber *x, CouNumber *lb, CouNumber *ub, bool copy=true)
save current point and start using another
JnlstPtr jnlst_
SmartPointer to the Journalist.
DomainPoint * current()
return current point
const Ipopt::EJournalCategory J_COUENNE(Ipopt::J_USER8)
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Add list of options to be read from file.
const Ipopt::EJournalCategory J_PROBLEM(Ipopt::J_USER4)
void fillObjCoeff(double *&)
Fill vector with coefficients of objective function.
void fint fint fint real fint real * x
CouNumber * Lb() const
Return vector of lower bounds.
bool isInteger(CouNumber x)
is this number integer?