/* $Id$ * * Name: impliedBounds-sum.cpp * Author: Pietro Belotti * Purpose: inferring bounds on monomials in a sum * * (C) Carnegie-Mellon University, 2006-10. * This file is licensed under the Eclipse Public License (EPL) */ #include #include "CoinHelperFunctions.hpp" #include "CouenneExprSum.hpp" using namespace Couenne; #define ALMOST_INF (1e-5 * COUENNE_INFINITY) int exprSum::impliedBoundSum (CouNumber wl, CouNumber wu, std::vector &xl, std::vector &xu, std::vector > &nl, std::vector > &nu) { CouNumber sumLB = 0, sumUB = 0; int nImpr = 0, n = xl.size (), infLo = -1, infUp = -1; // check lower bounds for (int i=0; i= 0) {infLo = -2; break;} else infLo = i; else sumLB += l; } // check upper bounds for (int i=0; i ALMOST_INF) if (infUp >= 0) {infUp = -2; break;} else infUp = i; else sumUB += u; } // if more than two unbounded quantities on both sides, bail out if ((infUp == -2) && (infLo == -2)) return 0; // new lower bounds //////////////////////////////////////////////////// if (infLo == -1) { // none of the "first" components is unbounded from below for (int i=0; i (i, nb)); nImpr ++; } } } else if (infLo >= 0) { // exactly one of them is, can improve bound on that one only CouNumber nb = wu - sumLB; if (nb < xu [infLo]) { nu.push_back (std::pair (infLo, nb)); nImpr ++; } } // new upper bounds //////////////////////////////////////////////////// if (infUp == -1) { // none of the "first" components is unbounded from below for (int i=0; i xl [i]) { nl.push_back (std::pair (i, nb)); nImpr ++; } } } else if (infUp >= 0) { // exactly one of them is, can improve bound on that one only CouNumber nb = wl - sumUB; if (nb < xl [infLo]) { nl.push_back (std::pair (infUp, nb)); nImpr ++; } } return nImpr; }