16 #include "CoinFinite.hpp"
17 #include "CoinHelperFunctions.hpp"
19 using namespace Couenne;
30 {
return (e0 -> Index () < e1 -> Index ());}
50 printf (
"################ implied bounds: [%g,%g], ", wl, wu);
51 print (); printf (
"\n");
57 std::set <exprVar *, compVar> indexSet;
60 for (lincoeff::iterator el =
lcoeff_.begin (); el !=
lcoeff_.end (); ++el)
61 indexSet.insert (el -> first);
64 for (sparseQ::iterator row =
matrix_.begin (); row !=
matrix_.end (); ++row) {
66 indexSet.insert (row -> first);
68 for (sparseQcol::iterator col = row -> second.begin (); col != row -> second.end (); ++col)
69 indexSet.insert (col -> first);
77 int indInfLo = -1, indInfUp = -1;
82 qMin = (*qlb) ();
delete qlb;
83 qMax = (*qub) ();
delete qub;
89 if ((indInfLo == -2) &&
94 printf (
"1st phase... inf=(%d,%d) q=[%g,%g].\n", indInfLo, indInfUp, qMin, qMax);
95 for (std::set <int>:: iterator iter = indexSet.begin ();
96 iter != indexSet.end (); ++iter)
97 printf (
"%4d [%+6g %+6g]\n", *iter, l [iter ->
Index ()], u [iter ->
Index ()]);
111 if (((indInfLo == -2) && (indInfUp == -2)) ||
112 ((indInfLo == -1) && (indInfUp == -1) &&
113 (qMin > wl) && (qMax < wu)))
117 printf (
"2nd phase... inf=(%d,%d) q=[%g,%g].\n", indInfLo, indInfUp, qMin, qMax);
126 minindex = (*(indexSet.begin ())) ->
Index (),
127 maxindex = (*(indexSet.rbegin ())) ->
Index (),
128 nvars = maxindex - minindex + 1;
138 CoinFillN (linCoeMin, nvars, 0.);
139 CoinFillN (linCoeMax, nvars, 0.);
140 CoinFillN (qii, nvars, 0.);
141 CoinFillN (bCutLb, nvars, 0.);
142 CoinFillN (bCutUb, nvars, 0.);
145 for (lincoeff::iterator el =
lcoeff_.begin (); el !=
lcoeff_.end (); ++el) {
148 int ind = el -> first ->
Index ();
157 linCoeMin [ind] += coe;
158 linCoeMax [ind] += coe;
170 printf (
"linear filling (%d,%d): -----------------------\n", minindex, maxindex);
171 for (std::set <int>:: iterator iter = indexSet.begin ();
172 iter != indexSet.end (); ++iter)
173 printf (
"%4d [%+6g %+6g] [%+6g %+6g]\n", iter ->
Index (),
174 linCoeMin [iter ->
Index () - minindex], linCoeMax [iter ->
Index () - minindex],
175 bCutLb [iter ->
Index () - minindex], bCutUb [iter ->
Index () - minindex]);
179 for (sparseQ::iterator row =
matrix_.begin (); row !=
matrix_.end (); ++row) {
181 for (sparseQcol::iterator col = row -> second.begin (); col != row -> second.end (); ++col) {
184 qi = row -> first ->
Index (),
185 qj = col -> first ->
Index ();
188 li = l [qi], lj = l [qj],
189 ui = u [qi], uj = u [qj];
198 maxbUb = CoinMax (fabs (li), fabs (ui)),
199 maxbLb = (li >= 0) ? (li) : (ui <= 0) ? (ui) : 0;
203 maxbUb *= maxbUb * coe;
204 maxbLb *= maxbLb * coe;
207 bCutUb [qi] += maxbUb;
208 bCutLb [qi] += maxbLb;
210 bCutUb [qi] += maxbLb;
211 bCutLb [qi] += maxbUb;
219 if (coe > 0) {b1 = l; b2 = u;}
220 else {b1 = u; b2 = l;}
228 linCoeMin [qi] += coe * b1 [qj];
229 linCoeMin [qj] += coe * b1 [qi];
231 linCoeMax [qi] += coe * b2 [qj];
232 linCoeMax [qj] += coe * b2 [qi];
235 addLo = CoinMin (CoinMin (li*lj, ui*uj),
236 CoinMin (ui*lj, li*uj)),
237 addUp = CoinMax (CoinMax (li*lj, ui*uj),
238 CoinMax (ui*lj, li*uj));
247 bCutLb [qi] += addLo; bCutUb [qi] += addUp;
248 bCutLb [qj] += addLo; bCutUb [qj] += addUp;
250 bCutLb [qi] += addUp; bCutUb [qi] += addLo;
251 bCutLb [qj] += addUp; bCutUb [qj] += addLo;
258 printf (
"quad filling: -----------------------\n");
259 for (std::set <int>:: iterator iter = indexSet.begin ();
260 iter != indexSet.end (); ++iter)
261 printf (
"%4d [%+6g %+6g] [%+6g %+6g]\n", *iter,
262 linCoeMin [iter ->
Index () - minindex], linCoeMax [iter ->
Index () - minindex],
263 bCutLb [iter ->
Index () - minindex], bCutUb [iter ->
Index () - minindex]);
269 bool one_updated =
false;
271 for (std::set <exprVar *, compVar>:: iterator iter = indexSet.begin ();
272 iter != indexSet.end (); ++iter) {
278 int ind = (*iter) ->
Index (),
279 indn = ind - minindex;
282 al = linCoeMin [indn],
283 au = linCoeMax [indn],
294 if ((al > 0) || (au < 0)) {
304 l_b = wl - qMax + bCutUb [indn],
305 u_b = wu - qMin + bCutLb [indn];
309 if ((indInfUp == -1) || (indInfUp == ind))
310 updatedL =
updateBound (-1, l + ind, (l_b) / ((l_b < 0) ? al : au)) || updatedL;
311 if ((indInfLo == -1) || (indInfLo == ind))
312 updatedU =
updateBound (+1, u + ind, (u_b) / ((u_b < 0) ? au : al)) || updatedU;
315 if (l [ind] > ol) printf (
"0. l%d: %g --> %g\n", ind, ol, l [ind]);
316 if (u [ind] < ou) printf (
"0. u%d: %g --> %g\n", ind, ou, u [ind]);
320 if ((indInfLo == -1) || (indInfLo == ind))
321 updatedL =
updateBound (-1, l + ind, (u_b) / ((u_b < 0) ? al : au)) || updatedL;
322 if ((indInfUp == -1) || (indInfUp == ind))
323 updatedU =
updateBound (+1, u + ind, (l_b) / ((l_b < 0) ? au : al)) || updatedU;
326 if (l [ind] > ol) printf (
"1. l%d: %g --> %g\n", ind, ol, l [ind]);
327 if (u [ind] < ou) printf (
"1. u%d: %g --> %g\n", ind, ou, u [ind]);
336 if ((indInfLo != -1) &&
355 deltaSecond = 4 * q * (qMin - bCutLb [indn] - wu),
356 deltaUp = au*au - deltaSecond,
357 deltaLo = al*al - deltaSecond;
361 if ((deltaUp >= 0) &&
364 updatedL =
updateBound (-1, l + ind, (- au - sqrt (deltaUp)) / (2*q)) || updatedL;
365 updatedU =
updateBound (+1, u + ind, (- al + sqrt (deltaLo)) / (2*q)) || updatedU;
368 if (l [ind] > ol) printf (
"2. l%d: %g --> %g\n", ind, ol, l [ind]);
369 if (u [ind] < ou) printf (
"2. u%d: %g --> %g\n", ind, ou, u [ind]);
372 }
else if (deltaUp >= 0) {
374 updatedL =
updateBound (-1, l + ind, (- au - sqrt (deltaUp)) / (2*q)) || updatedL;
375 updatedU =
updateBound (+1, u + ind, (- au + sqrt (deltaUp)) / (2*q)) || updatedU;
379 if (l [ind] > ol) printf (
"3. l%d: %g --> %g\n", ind, ol, l [ind]);
380 if (u [ind] < ou) printf (
"3. u%d: %g --> %g\n", ind, ou, u [ind]);
383 }
else if (deltaLo >= 0) {
385 updatedL =
updateBound (-1, l + ind, (- al - sqrt (deltaLo)) / (2*q)) || updatedL;
386 updatedU =
updateBound (+1, u + ind, (- al + sqrt (deltaLo)) / (2*q)) || updatedU;
390 if (l [ind] > ol) printf (
"4. l%d: %g --> %g\n", ind, ol, l [ind]);
391 if (u [ind] < ou) printf (
"4. u%d: %g --> %g\n", ind, ou, u [ind]);
396 updatedL =
updateBound (-1, l+ind, +1) || updatedL;
397 updatedU =
updateBound (+1, u+ind, -1) || updatedU;
400 printf (
"5. infeasible!\n");
420 if ((indInfUp != -1) &&
425 deltaSecond = 4 * q * (qMax - bCutUb [indn] - wl),
426 deltaUp = au*au - deltaSecond,
427 deltaLo = al*al - deltaSecond;
431 if ((deltaUp >= 0) &&
434 updatedL =
updateBound (-1, l + ind, (al - sqrt (deltaLo)) / (-2*q)) || updatedL;
435 updatedU =
updateBound (+1, u + ind, (au + sqrt (deltaUp)) / (-2*q)) || updatedU;
438 if (l [ind] > ol) printf (
"6. l%d: %g --> %g\n", ind, ol, l [ind]);
439 if (u [ind] < ou) printf (
"6. u%d: %g --> %g\n", ind, ou, u [ind]);
441 }
else if (deltaUp >= 0) {
443 updatedL =
updateBound (-1, l + ind, (au - sqrt (deltaUp)) / (-2*q)) || updatedU;
444 updatedU =
updateBound (+1, u + ind, (au + sqrt (deltaUp)) / (-2*q)) || updatedL;
448 if (l [ind] > ol) printf (
"7. l%d: %g --> %g\n", ind, ol, l [ind]);
449 if (u [ind] < ou) printf (
"7. u%d: %g --> %g\n", ind, ou, u [ind]);
452 }
else if (deltaLo >= 0) {
454 updatedL =
updateBound (-1, l + ind, (al - sqrt (deltaLo)) / (-2*q)) || updatedL;
455 updatedU =
updateBound (+1, u + ind, (al + sqrt (deltaLo)) / (-2*q)) || updatedU;
458 if (l [ind] > ol) printf (
"8. l%d: %g --> %g\n", ind, ol, l [ind]);
459 if (u [ind] < ou) printf (
"8. u%d: %g --> %g\n", ind, ou, u [ind]);
464 updatedL =
updateBound (-1, l+ind, +1) || updatedL;
465 updatedU =
updateBound (+1, u+ind, -1) || updatedU;
468 printf (
"9. infeasible\n");
bool updateBound(register int sign, register CouNumber *dst, register CouNumber src)
updates maximum violation.
status of lower/upper bound of a variable, to be checked/modified in bound tightening ...
void setLower(ChangeStatus lower)
Structure for comparing variables.
CouNumber c0_
constant term
virtual bool isInteger()
is this expression integer?
void setUpper(ChangeStatus upper)
virtual int Index() const
Return index of variable (only valid for exprVar and exprAux)
auxSign
"sign" of the constraint defining an auxiliary.
lincoeff lcoeff_
coefficients and indices of the linear term
virtual void getBounds(expression *&, expression *&)
Get lower and upper bound of an expression (if any)
double CouNumber
main number type in Couenne
virtual bool impliedBound(int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign=expression::AUX_EQ)
implied bound processing
void computeQuadFiniteBound(CouNumber &qMin, CouNumber &qMax, CouNumber *l, CouNumber *u, int &indInfLo, int &indInfUp)
return lower and upper bound of quadratic expression
virtual void print(std::ostream &=std::cout, bool=false) const
Print expression to an iostream.