impliedBounds-sum.cpp
Go to the documentation of this file.
1 /* $Id: impliedBounds-sum.cpp 490 2011-01-14 16:07:12Z pbelotti $
2  *
3  * Name: impliedBounds-sum.cpp
4  * Author: Pietro Belotti
5  * Purpose: inferring bounds on monomials in a sum
6  *
7  * (C) Carnegie-Mellon University, 2006-10.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include <vector>
12 
13 #include "CoinHelperFunctions.hpp"
14 #include "CouenneExprSum.hpp"
15 
16 using namespace Couenne;
17 
18 #define ALMOST_INF (1e-5 * COUENNE_INFINITY)
19 
21  CouNumber wu,
22  std::vector <CouNumber> &xl,
23  std::vector <CouNumber> &xu,
24  std::vector <std::pair <int, CouNumber> > &nl,
25  std::vector <std::pair <int, CouNumber> > &nu) {
26  CouNumber
27  sumLB = 0,
28  sumUB = 0;
29 
30  int
31  nImpr = 0,
32  n = xl.size (),
33  infLo = -1,
34  infUp = -1;
35 
36  // check lower bounds
37  for (int i=0; i<n; i++) {
38  CouNumber l = xl [i];
39  if (l < -ALMOST_INF)
40  if (infLo >= 0) {infLo = -2; break;}
41  else infLo = i;
42  else sumLB += l;
43  }
44 
45  // check upper bounds
46  for (int i=0; i<n; i++) {
47  CouNumber u = xu [i];
48  if (u > ALMOST_INF)
49  if (infUp >= 0) {infUp = -2; break;}
50  else infUp = i;
51  else sumUB += u;
52  }
53 
54  // if more than two unbounded quantities on both sides, bail out
55  if ((infUp == -2) &&
56  (infLo == -2))
57  return 0;
58 
59  // new lower bounds ////////////////////////////////////////////////////
60 
61  if (infLo == -1) { // none of the "first" components is unbounded from below
62 
63  for (int i=0; i<n; i++) {
64 
65  CouNumber nb = wu - sumLB + xl [i];
66  if (nb < xu [i]) {
67  nu.push_back (std::pair <int, CouNumber> (i, nb));
68  nImpr ++;
69  }
70  }
71 
72  } else if (infLo >= 0) { // exactly one of them is, can improve bound on that one only
73 
74  CouNumber nb = wu - sumLB;
75  if (nb < xu [infLo]) {
76  nu.push_back (std::pair <int, CouNumber> (infLo, nb));
77  nImpr ++;
78  }
79  }
80 
81  // new upper bounds ////////////////////////////////////////////////////
82 
83  if (infUp == -1) { // none of the "first" components is unbounded from below
84 
85  for (int i=0; i<n; i++) {
86 
87  CouNumber nb = wl - sumUB + xu [i];
88  if (nb > xl [i]) {
89  nl.push_back (std::pair <int, CouNumber> (i, nb));
90  nImpr ++;
91  }
92  }
93 
94  } else if (infUp >= 0) { // exactly one of them is, can improve bound on that one only
95 
96  CouNumber nb = wl - sumUB;
97  if (nb < xl [infLo]) {
98  nl.push_back (std::pair <int, CouNumber> (infUp, nb));
99  nImpr ++;
100  }
101  }
102 
103  return nImpr;
104 }
#define ALMOST_INF
double CouNumber
main number type in Couenne
fint nb
int impliedBoundSum(CouNumber wl, CouNumber wu, std::vector< CouNumber > &xl, std::vector< CouNumber > &xu, std::vector< std::pair< int, CouNumber > > &nl, std::vector< std::pair< int, CouNumber > > &nu)
inferring bounds on factors of a product
fint nu
void fint * n