CouenneFPpool.cpp
Go to the documentation of this file.
1 /* $Id: CouenneFPpool.cpp 1061 2014-02-01 19:22:28Z pbelotti $
2  *
3  * Name: CouenneFPpool.cpp
4  * Authors: Pietro Belotti
5  * Timo Berthold, ZIB Berlin
6  * Purpose: Pool of MILP- (and why not? NLP-) feasible solutions for
7  * restart use in the Feasibility Pump
8  *
9  * This file is licensed under the Eclipse Public License (EPL)
10  */
11 
12 #include "CoinHelperFunctions.hpp"
13 
14 #include "CouenneProblem.hpp"
15 #include "CouenneFPpool.hpp"
16 #include "CouenneFeasPump.hpp"
17 #include "CouenneExprVar.hpp"
18 #include "CouenneExprAux.hpp"
19 
20 static const double COMP_TOLERANCE = COUENNE_EPS; // not global
21 
22 using namespace Couenne;
23 
26 
27  x_ (NULL),
28  n_ (p -> nVars ()),
29  nNLinf_ (0),
30  nIinf_ (0),
31  objVal_ (0.),
32  maxNLinf_ (0.),
33  maxIinf_ (0.),
34  copied_ (copied),
35  problem_ (p) {
36 
40 
41  if (copied_) {
42  x_ = x;
43  return;
44  }
45 
46  x_ = CoinCopyOfArray (x, p -> nVars ());
47 
48  for (std::vector <exprVar *>::iterator i = p -> Variables (). begin ();
49  i != p -> Variables (). end ();
50  ++i) {
51 
52  if ((*i) -> Multiplicity () <= 0)
53  continue;
54 
55  CouNumber
56  vval = (**i) ();
57 
58  if ((*i) -> isInteger ()) {
59 
60  double inf = CoinMax (vval - floor (vval + COUENNE_EPS),
61  ceil (vval - COUENNE_EPS) - vval);
62 
63  if (inf > COUENNE_EPS) {
64 
65  ++nIinf_;
66 
67  if (inf > maxIinf_)
68  maxIinf_ = inf;
69  }
70  }
71 
72  if (((*i) -> Type () == AUX) &&
73  ((*i) -> Image () -> Linearity () > LINEAR)) {
74 
75  double
76  diff = 0.,
77  fval = (*((*i) -> Image ())) ();
78 
79  if ((*i) -> sign () != expression::AUX_GEQ) diff = CoinMax (diff, vval - fval);
80  else if ((*i) -> sign () != expression::AUX_LEQ) diff = CoinMax (diff, fval - vval);
81 
82  if (diff > COUENNE_EPS) {
83 
84  ++nNLinf_;
85 
86  if (diff > maxNLinf_)
87  maxNLinf_ = diff;
88  }
89  }
90  }
91 }
92 
93 
96  x_ (src.x_ ? CoinCopyOfArray (src.x_, src.n_) : NULL),
97  n_ (src.n_),
98  nNLinf_ (src.nNLinf_),
99  nIinf_ (src.nIinf_),
100  objVal_ (src.objVal_),
101  maxNLinf_ (src.maxNLinf_),
102  maxIinf_ (src.maxIinf_),
103  copied_ (false),
104  problem_ (src.problem_) {}
105 
106 
109 
110  x_ = src.x_ ? CoinCopyOfArray (src.x_, src.n_) : NULL;
111  n_ = src.n_;
112  nNLinf_ = src.nNLinf_;
113  nIinf_ = src.nIinf_;
114  objVal_ = src.objVal_;
115  maxNLinf_ = src.maxNLinf_;
116  maxIinf_ = src.maxIinf_;
117  copied_ = false;
118  problem_ = src.problem_;
119 
120  return *this;
121 }
122 
125 
126  if (x_ && !copied_)
127  delete [] x_;
128 }
129 
131 bool CouenneFPsolution::compare (const CouenneFPsolution &other, enum what_to_compare comparedTerm) const {
132 
133  switch (comparedTerm) {
134 
135  case SUM_INF: if (maxNLinf_ + maxIinf_ < other.maxNLinf_ + other.maxIinf_) return true;
136  case OBJVAL: if (objVal_ < other.objVal_ - COUENNE_EPS * CoinMax (1., CoinMax (objVal_, other.objVal_))) return true;
137  case SUM_NINF: if (nNLinf_ + nIinf_ < other.nNLinf_ + other.nIinf_) return true;
138  // so that if objective is close these two solutions will be deemed equal
139 
140  case INTEGER_VARS: {
141 
142  // lexicographical comparison: unless the two solutions have the
143  // same integer subvector, comparison will tell them apart
144 
145  for (std::vector <exprVar *>::iterator i = problem_ -> Variables (). begin ();
146  i != problem_ -> Variables (). end ();
147  ++i)
148 
149  if (((*i) -> Multiplicity () > 0) &&
150  (*i) -> isInteger ()) {
151 
152  int indVar = (*i) -> Index ();
153 
154  // LEXICOGRAPHICAL ORDERING: return true upon finding the
155  // first element with lower element
156 
157 #if 0
158  if (0) {
159  printf (" (%d,%g,%g,%g)", indVar, x_ [indVar], other.x_ [indVar], x_ [indVar] - other.x_ [indVar]);
160 
161  if (x_ [indVar] < other.x_ [indVar] - COUENNE_EPS)
162  printf ("\n-----\n");
163  }
164 #endif
165  if (x_ [indVar] < other.x_ [indVar] - COUENNE_EPS)
166  return true;
167  }
168 
169  //printf ("\n####\n");
170  return false;
171  }
172 
173  case ALL_VARS: {
174  // lexicographical comparison: unless the two solutions have the
175  // same subvector, comparison will tell them apart
176 
177  for (std::vector <exprVar *>::iterator i = problem_ -> Variables (). begin ();
178  i != problem_ -> Variables (). end ();
179  ++i)
180 
181  if ((*i) -> Multiplicity () > 0) {
182 
183  int indVar = (*i) -> Index ();
184 
185  if (x_ [indVar] < other.x_ [indVar] + COUENNE_EPS)
186  return true;
187  }
188 
189  return false;
190  }
191  }
192 
193  printf ("CouenneFPsolution::compare: bad compared term\n");
194  abort ();
195 }
196 
197 
200  set_ (src.set_),
201  problem_ (src.problem_) {}
202 
203 
206 
207  set_ = src.set_;
208  problem_ = src.problem_;
209 
210  return *this;
211 }
212 
215  const CouenneFPsolution &two) const {
216 
217  return one. compare (two, comparedTerm_);
218 
219  // register const double
220  // *x1 = one.x (),
221  // *x2 = two.x ();
222 
223  // register int n = one.n ();
224 
225  // while (n--)
226  // if ((*x1++ - *x2++) <= COMP_TOLERANCE)
227  // return true;
228 
229  // return false;
230 }
231 
234 void CouenneFPpool::findClosestAndReplace (double *&sol, const double *nSol, int nvars) {
235 
236  double bestdist = COIN_DBL_MAX;
237  std::set <CouenneFPsolution, compareSol>::iterator bestsol = set_. end ();
238 
239  if( nSol )
240  {
241  for (std::set <CouenneFPsolution, compareSol>::iterator i = set_. begin ();
242  i != set_. end (); ++i)
243  {
244  //compute distance of pool solution and NLP solution
245 
246  register double
247  dist = 0.0,
248  delta;
249 
250  const register double
251  *x = i -> x (),
252  *s = nSol;
253 
254  register bool move_on = false;
255 
256  for (int j = nvars, k=0; j--; ++k) {
257 
258  delta = *x++ - *s++;
259 
262  if (problem_ -> Var (k) -> Multiplicity () <= 0)
263  continue;
264 
265  dist += delta * delta;
266 
267  if (dist >= bestdist) { // interrupt check of this solution
268  // if already above current best
269  move_on = true;
270  break;
271  }
272  }
273 
274  if (move_on)
275  continue;
276 
277  //update best solution
278  if( dist < bestdist )
279  {
280  bestdist = dist;
281  bestsol = i;
282  }
283  }
284  }
285  else
286  bestsol = set_. begin ();
287 
288  if( bestsol != set_. end () )
289  {
290  delete [] sol;
291  sol = CoinCopyOfArray ((*bestsol).x(), nvars);
292  set_. erase(bestsol);
293  }
294 }
CouenneFPsolution(CouenneProblem *p, CouNumber *x, bool copied=false)
CouenneProblem-aware constructor.
Pool of solutions.
static Bigint * diff(Bigint *a, Bigint *b)
Definition: OSdtoa.cpp:1120
CouNumber maxNLinf_
maximum NL infeasibility
bool operator()(const CouenneFPsolution &one, const CouenneFPsolution &two) const
compare, base version
bool compare(const CouenneFPsolution &other, enum what_to_compare comparedTerm) const
basic comparison procedure – what to compare depends on user&#39;s choice
int n_
number of variables (for independence from CouenneProblem)
int nNLinf_
number of NL infeasibilities
static char * j
Definition: OSdtoa.cpp:3622
what_to_compare
what term to compare: the sum of infeasibilities, the sum of numbers of infeasible terms...
CouenneFPsolution & operator=(const CouenneFPsolution &src)
assignment
Class containing a solution with infeasibility evaluation.
void findClosestAndReplace(double *&sol, const double *nSol, int nvars)
finds, in pool, solution x closest to sol; removes it from the pool and overwrites it to sol ...
CouenneFPpool(CouenneProblem *p, enum what_to_compare c)
simple constructor (empty pool)
CouenneFPpool & operator=(const CouenneFPpool &src)
assignment
fint end
static enum Couenne::what_to_compare comparedTerm_
bool copied_
This is a temporary copy, not really a solution holder.
CouenneProblem * problem_
Problem pointer.
Class for MINLP problems with symbolic information.
const double * x() const
returns vector
void fint fint * k
void fint fint fint fint fint fint fint fint fint fint real real real real real real real real * s
#define COUENNE_EPS
double CouNumber
main number type in Couenne
CouNumber objVal_
objective function value
CouNumber * x_
solution
int nIinf_
number of integer infeasibilities
The in-memory representation of the variables element.
Definition: OSInstance.h:83
std::set< CouenneFPsolution, compareSol > set_
Pool.
CouenneProblem * problem_
holds pointer to problem to check integrality in comparison of integer variables
static const double COMP_TOLERANCE
CouNumber maxIinf_
maximum integer infeasibility
void fint fint fint real fint real * x
bool isInteger(CouNumber x)
is this number integer?