11 #include "CoinHelperFunctions.hpp"
19 using namespace Couenne;
21 #define MAX_ITER 3 // max # fake tightening (inner) iterations
22 #define AGGR_MUL 2 // the larger, the more conservative. Must be > 0
23 #define AGGR_DIV 2 // the smaller, the more conservative. Must be > 1
34 #define LARGE_BOUND 1e10
51 if (x < -
COUENNE_EPS)
return (CoinMin (0., (x+ub)/2));
67 else if (x >
COUENNE_EPS)
return (CoinMax (0.,(x+lb)/2));
98 objind =
Obj (0) -> Body () -> Index ();
109 outer = (direction ? oub : olb) [index],
116 jnlst_ -> Printf (Ipopt::J_ERROR,
J_BOUNDTIGHTENING,
" x_%d. x = %10g, lb = %g, cutoff = %g-----------------\n", index,xcur,objind >= 0 ?
Lb (objind) : 0.,
getCutOff());
122 for (
int iter = 0; iter <
MAX_ITER; iter++) {
129 if ( (direction && (inner > outer + .5)) ||
130 (!direction && (inner < outer - .5))) {
143 CoinCopyN (
Lb (), ncols, olb);
144 CoinCopyN (
Ub (), ncols, oub);
147 CoinCopyN (chg_bds, ncols, f_chg);
154 if ( (direction && ((fb < inner) || (fb > outer))) ||
155 (!direction && ((fb > inner) || (fb < outer))))
156 fb = 0.5 * (inner + outer);
170 char c1 = direction ?
'-' :
'>', c2 = direction ?
'<' :
'-';
171 printf (
" # x%d = %g iter %3d: [%+10g -%c %+10g %c- %+10g] /\\/\\ ",index,xcur,iter,olb[index],c1,fb,c2, oub [index]);
172 printf (
" [%10g,%10g]<%g,%g>=> ",
Lb (index),
Ub (index),CoinMin(inner,outer),CoinMax(inner,outer));
176 feasible =
btCore (f_chg),
179 jnlst_ -> Printf (Ipopt::J_ERROR,
J_BOUNDTIGHTENING,
" [%10g,%10g] lb = %g {fea=%d,btr=%d} ",
Lb (index),
Ub (index), objind >= 0 ?
Lb (objind) : 0., feasible,betterbds);
181 if (feasible && !betterbds) {
187 CoinCopyN (chg_bds, ncols, f_chg);
188 CoinCopyN (olb, ncols,
Lb ());
189 CoinCopyN (oub, ncols,
Ub ());
206 (
optimum_ [index] >= olb [index]) &&
209 (
optimum_ [index] <= oub [index]) &&
213 "fake tightening CUTS optimum: x%d=%g in [%g,%g] but not in [%g,%g]\n",
214 index, olb [index], oub [index],
Lb (index),
Ub (index));
243 oub [index] =
Ub (index) = intvar ? floor (fb +
COUENNE_EPS) : fb;
248 olb [index] =
Lb (index) = intvar ? ceil (fb -
COUENNE_EPS) : fb;
258 CoinCopyN (chg_bds, ncols, f_chg);
259 CoinCopyN (olb, ncols,
Lb ());
260 CoinCopyN (oub, ncols,
Ub ());
264 if (!(
btCore (chg_bds))) {
267 "\n pruned by Probing\n");
274 CoinCopyN (
Lb (), ncols, olb);
275 CoinCopyN (
Ub (), ncols, oub);
291 if ((!direction && ((inner > ub) || (outer < lb))) ||
292 ( direction && ((inner < lb) || (outer > ub)))) {
296 inner = direction ? lb : ub;
297 outer = direction ? ub : lb;
308 if (direction) fb = inner +
exp (
log (10.) * L/2);
309 else fb = inner -
exp (
log (10.) * L/2);
311 }
else fb = (inner + outer)/2;
325 if (tightened)
Jnlst()->Printf(Ipopt::J_MOREVECTOR,
J_BOUNDTIGHTENING,
" [x%2d] pruned %s [%g, %g] -- lb = %g cutoff = %g\n", index,direction?
"right":
"left", olb[index],oub[index], objind >= 0 ?
Lb (objind) : 0.,
getCutOff ());
327 return tightened ? 1 : 0;
CouNumber fictBounds(char direction, CouNumber x, CouNumber lb, CouNumber ub)
int nVars() const
Total number of variables.
static Bigint * diff(Bigint *a, Bigint *b)
int fake_tighten(char direction, int index, const double *X, CouNumber *olb, CouNumber *oub, t_chg_bounds *chg_bds, t_chg_bounds *f_chg) const
single fake tightening.
CouExpr & log(CouExpr &e)
status of lower/upper bound of a variable, to be checked/modified in bound tightening ...
void setLower(ChangeStatus lower)
CouNumber getCutOff() const
Get cutoff.
void setUpper(ChangeStatus upper)
CouExpr & exp(CouExpr &e)
ConstJnlstPtr Jnlst() const
Provide Journalist.
bool btCore(t_chg_bounds *chg_bds) const
core of the bound tightening procedure
const Ipopt::EJournalCategory J_BOUNDTIGHTENING(Ipopt::J_USER2)
std::vector< exprVar * > variables_
Variables (original, auxiliary, and defined)
CouNumber * Ub() const
Return vector of upper bounds.
CouNumber * optimum_
Best solution known to be loaded from file – for testing purposes.
double CouNumber
main number type in Couenne
JnlstPtr jnlst_
SmartPointer to the Journalist.
CouenneObjective * Obj(int i) const
i-th objective
void fint fint fint real fint real * x
CouNumber * Lb() const
Return vector of lower bounds.
bool isInteger(CouNumber x)
is this number integer?