TwoImpliedIneqCombine.cpp
Go to the documentation of this file.
1 /* $Id: TwoImpliedIneqCombine.cpp 939 2013-01-12 19:53:30Z pbelotti $
2  *
3  * Name: TwoImpliedCombine.cpp
4  * Author: Pietro Belotti
5  * Purpose: Bound reduction using two inequalities from the LP relaxation
6  *
7  * (C) Pietro Belotti, 2010.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include <stdlib.h>
12 
13 #include "CglCutGenerator.hpp"
14 #include "CouenneTwoImplied.hpp"
15 #include "CoinPackedMatrix.hpp"
16 #include "CouennePrecisions.hpp"
17 #include "CouenneProblem.hpp"
18 #include "CouenneExprVar.hpp"
19 
20 #define MIN_DENOM 1.e-10
21 
22 namespace Couenne {
23 
24 enum signum {NEG, POS, DN, UP};
25 
26 //#define DEBUG
27 
28 // type for alphas ////////////////////////////////////////////////
29 
30 typedef struct {
31 
32  double alpha;
33  int indVar;
34  enum signum sign; // defines behavior of convex combination within
35  // [0,1]: always negative, always positive, + ->
36  // -, and - -> +
37 } threshold;
38 
39 
40 // compare two threshold values ///////////////////////////////////
41 
42 int compthres (register const void *t1,
43  register const void *t2) {
44 
45  register double
46  a1 = (*(threshold **) t1) -> alpha,
47  a2 = (*(threshold **) t2) -> alpha;
48 
49  return ((a1 < a2) ? -1 :
50  (a1 > a2) ? 1 : 0);
51 }
52 
53 // structure to sort indices with respective values
54 
55 struct indPosPair {
56 
57  int index;
58  int position;
59 };
60 
61 // compare two pairs (index,value) ///////////////////////////////////
62 
63 int compPair (register const void *p1,
64  register const void *p2) {
65 
66  register int
67  i1 = ((struct indPosPair *) p1) -> index,
68  i2 = ((struct indPosPair *) p2) -> index;
69 
70  return ((i1 < i2) ? -1 :
71  (i1 > i2) ? 1 : 0);
72 }
73 
74 
75 //
76 // Combines two inequalities whose indices, bounds, and coefficients
77 // are defined by the arguments ind, l and u, and a, respectively.
78 //
79 
81  int n1,
82  int n2,
83  const int *ind1c, // indices
84  const int *ind2c,
85  double *sa1, // coeff (sparse array)
86  double *sa2, // DO NOT INVERT (already done at caller)
87  const double *a1c, // coeff
88  const double *a2c,
89  double *clb, // variable bounds
90  double *cub,
91  double l1, // constraint bounds
92  double l2,
93  double u1,
94  double u2,
95  bool *isInteger,
96  int sign) { // invert second constraint? -1: yes, +1: no
97 
98  // first, sort ind1/a1 and ind2/a2 w.r.t. indices. They may not be
99  // sorted and this messes up the while loop below.
100 
101  int
102  *ind1 = new int [n1],
103  *ind2 = new int [n2];
104 
105  double
106  *a1 = new double [n1],
107  *a2 = new double [n2];
108 
109  CouNumber
110  *Lb = p -> Lb (),
111  *Ub = p -> Ub ();
112 
113  struct indPosPair *pairs = new struct indPosPair [CoinMax (n1,n2)];
114 
115  // re-order ind1 and a1, ind2 and a2 ///////////////////////////////////////////
116 
117  for (int i=0; i<n1; i++) {
118  pairs [i]. index = ind1c [i];
119  pairs [i]. position = i;
120  }
121 
122  // This is not very wise: qsort behaves horribly (that is, O(n^2))
123  // on already sorted arrays (if the pivot element is the last one).
124 
125  qsort (pairs, n1, sizeof (indPosPair), compPair);
126 
127  for (int i=0; i<n1; i++) {
128 
129  int rightpos = pairs [i]. position;
130 
131  ind1 [i] = ind1c [rightpos];
132  a1 [i] = a1c [rightpos];
133  }
134 
136 
137  for (int i=0; i<n2; i++) {
138  pairs [i]. index = ind2c [i];
139  pairs [i]. position = i;
140  }
141 
142  qsort (pairs, n2, sizeof (indPosPair), compPair);
143 
144  for (int i=0; i<n2; i++) {
145 
146  int rightpos = pairs [i]. position;
147 
148  ind2 [i] = ind2c [rightpos];
149  a2 [i] = a2c [rightpos];
150  }
151 
152  delete [] pairs;
153 
154  // Set multiplier of second constraint, to be used with a2 but not
155  // with sa2.
156 
157  double signA;
158 
159  if (sign < 0) {
160 
161  double tmp = u2;
162  u2 = -l2;
163  l2 = -tmp;
164 
165  signA = -1.;
166 
167  } else signA = 1.;
168 
169 #ifdef DEBUG
170  printf ("here are the two ineqs (sign=%d):\n", sign);
171  printf (" 1: %g <=", l1); for (int i=0; i<n1; i++) printf (" %+g x%d", a1 [i], ind1 [i]);
172  printf ("<= %g\n 2: %g <=", u1, l2); for (int i=0; i<n2; i++) printf (" %+g x%d", signA * a2 [i], ind2 [i]); printf ("<= %g\n", u2);
173 #endif
174 
175  threshold
176  *alphas = new threshold [n1 + n2], // contains all alphas (there might be at most n1+n2-1, but let's be flexible)
177  **inalphas = new threshold* [n1 + n2], // points to those in [0,1[ (will be sorted)
178  *curalpha = alphas;
179 
180  int
181  i1 = 0,
182  i2 = 0,
183  cnt = 0,
184  incnt = 0;
185 
186  while (i1 < n1 ||
187  i2 < n2) {
188 
189  if (i1 < n1 && (i2 == n2 || ind1 [i1] < ind2 [i2])) {
190 
191  curalpha -> alpha = 1.;
192  curalpha -> sign = (a1 [i1] < 0.) ? NEG : POS;
193  curalpha -> indVar = ind1 [i1];
194 
195  cnt++;
196  i1++;
197 
198  } else if (i2 < n2 && (i1 == n1 || ind2 [i2] < ind1 [i1])) {
199 
200  curalpha -> alpha = 0.;
201  curalpha -> sign = (signA * a2 [i2] < 0.) ? NEG : POS;
202  curalpha -> indVar = ind2 [i2];
203 
204  cnt++;
205  i2++;
206 
207  } else {
208 
209  // the two indices are equal, < n1, n2 respectively, we may have
210  // an alpha in ]0,1[
211 
212  double a2i2 = signA * a2 [i2];
213 
214  curalpha -> alpha =
215  (a1 [i1] == a2i2) ?
216  -1. :
217  - a2i2 / (a1 [i1] - a2i2);
218 
219  if (curalpha -> alpha <= 0. ||
220  curalpha -> alpha >= 1.)
221 
222  curalpha -> sign = (a1 [i1] > 0.) ? POS : NEG;
223 
224  else
225 
226  curalpha -> sign =
227  (a1 [i1] == a2i2) ?
228  ((a1 [i1] < 0.) ? NEG : POS) :
229  ((a1 [i1] < 0.) ? DN : UP);
230 
231  curalpha -> indVar = ind1 [i1];
232 
233  if (curalpha -> alpha > 0. &&
234  curalpha -> alpha < 1.)
235  inalphas [incnt++] = curalpha;
236 
237  cnt++;
238  i1++;
239  i2++;
240  }
241 
242 #ifdef DEBUG
243  printf ("(%d,%g,%s) ",
244  curalpha -> indVar,
245  curalpha -> alpha,
246  (curalpha -> sign == NEG) ? "NEG" :
247  (curalpha -> sign == POS) ? "POS" :
248  (curalpha -> sign == DN) ? "DN" : "UP");
249 #endif
250 
251  curalpha++;
252  }
253 
254 #ifdef DEBUG
255  printf ("\n");
256 #endif
257 
258  // If none of them has an alpha in ]0,1[, nothing needs to be done.
259 
260  if (!incnt) {
261 
262  delete [] inalphas;
263  delete [] alphas;
264  delete [] ind1;
265  delete [] ind2;
266  delete [] a1;
267  delete [] a2;
268 
269  return 0;
270  }
271 
272  //----------------------------------------------------------------------
273  // Done setting up zeros of (alpha a'_i + (1-alpha) a''_i) x_i
274  //----------------------------------------------------------------------
275 
276  // Now all thresholds are defined. For all threshold in ]0,1[,
277  // determine if they define a convex combination of the two
278  // inequalities that allows to tighten the bounds of all variables
279  // with at least one nonzero coefficient in the two ineqs.
280 
281  int ntightened = 0;
282 
283  if (incnt > 1)
284  qsort (inalphas, incnt, sizeof (threshold *), compthres);
285 
286 #ifdef DEBUG
287  printf ("--sorted: ");
288  for (int i = 0; i < incnt; i++)
289  printf ("(%d,%g,%s) ",
290  inalphas [i] -> indVar,
291  inalphas [i] -> alpha,
292  (inalphas [i] -> sign == NEG) ? "NEG" :
293  (inalphas [i] -> sign == POS) ? "POS" :
294  (inalphas [i] -> sign == DN) ? "DN" : "UP");
295  printf ("\n");
296 #endif
297 
298  // Compute the max/min of the two constraint bodies. Consider bounds
299  // according to the sign of the CONVEX COMBINATION OF THE
300  // COEFFICIENT:
301  //
302  // a_i = alpha a1_i + (1-alpha) a2_i
303  //
304  // L1_min = sum {i in N} a1_i f-(i)
305  // L1_max = sum {i in N} a1_i f+(i)
306  //
307  // L2_min = sum {i in N} a2_i f-(i)
308  // L2_max = sum {i in N} a2_i f+(i)
309  //
310  // with f-(i) = l_i if a_i > 0 and a*_i > 0
311  // or a_i < 0 and a*_i < 0
312  // u_i otherwise;
313  //
314  // f+(i) = u_i if a_i > 0 and a*_i > 0
315  // or a_i < 0 and a*_i < 0
316  // l_i otherwise
317  //
318  // and a* is a1 or a2 depending on the equation.
319 
320  double
321  minSum1 = 0., minSum2 = 0.,
322  maxSum1 = 0., maxSum2 = 0.;
323 
324  int
325  mInfs = 0, // number of -inf summed to minSum 1 and 2 (both)
326  pInfs = 0; // +inf maxSum
327 
328  // The maximum sum in the constraint's body depends on the
329  // coefficients arising from the convex combination, but alpha=0
330  // at initialization.
331 
332  // compute for a_1 ////////////////////////////////////////////////////////
333 
334  for (int i=0; i<n1; i++) {
335 
336  int indVar1 = ind1 [i];
337 
338  double
339  a1i = a1 [i],
340  a2i = sa2 [indVar1],
341  clb1 = clb [indVar1],
342  cub1 = cub [indVar1];
343 
344  // if no corresponding term on other side, use coefficient of this
345  // inequality
346 
347  if (a2i == 0.)
348  a2i = a1i;
349 
350 #ifdef DEBUG
351  else if (fabs (a2i) < 1e-10)
352  printf ("\nNumerics in a2i\n\n");
353 #endif
354 
355  if (a2i < 0.) {
356 
357  bool zeroA = (fabs (sa2 [indVar1]) == 0.);
358 
359  if (cub1 > COUENNE_INFINITY/10) {if (zeroA) mInfs ++;} else minSum1 += a1i * cub1;
360  if (clb1 < - COUENNE_INFINITY/10) {if (zeroA) pInfs ++;} else maxSum1 += a1i * clb1;
361 
362  } else if (a2i > 0.) {
363 
364  bool zeroA = (fabs (sa2 [indVar1]) == 0.);
365 
366  if (clb1 < - COUENNE_INFINITY/10) {if (zeroA) mInfs ++;} else minSum1 += a1i * clb1;
367  if (cub1 > COUENNE_INFINITY/10) {if (zeroA) pInfs ++;} else maxSum1 += a1i * cub1;
368  }
369  }
370 
371  // compute for a_2 ////////////////////////////////////////////////////////
372 
373  for (int i=0; i<n2; i++) {
374 
375  int indVar2 = ind2 [i];
376 
377  double
378  a2i = a2 [i] * signA,
379  clb2 = clb [indVar2],
380  cub2 = cub [indVar2];
381 
382  if (a2i < 0.) {
383 
384  if (cub2 > COUENNE_INFINITY/10) mInfs ++; else minSum2 += a2i * cub2;
385  if (clb2 < - COUENNE_INFINITY/10) pInfs ++; else maxSum2 += a2i * clb2;
386 
387  } else {
388 
389  if (clb2 < - COUENNE_INFINITY/10) mInfs ++; else minSum2 += a2i * clb2;
390  if (cub2 > COUENNE_INFINITY/10) pInfs ++; else maxSum2 += a2i * cub2;
391  }
392  }
393 
394  // At this point, m[in,ax]Sum2 contain the finite max/min sums of
395  // the second term ax, and pInfs and mInfs the number of bounds
396  // that make the min/max sum infinite. We are at alpha=0,
397  // therefore this is the max/min sum of the whole convex
398  // combination of the two constraint bodies.
399 
400 #ifdef DEBUG
401  printf (" at alpha=zero, m[in,ax]sum[12] = (1:(%g,%g), 2:(%g,%g)), %d mInf, %d pInf\n",
402  minSum1, maxSum1,
403  minSum2, maxSum2,
404  mInfs, pInfs);
405 #endif
406 
407  // scan all alphas in ]0,1[ ///////////////////////////////////////////////
408 
409  // for all variables x[i], look for tighter lower/upper bounds on x[i]
410 
411  std::vector <std::pair <int, double> >
412  newLB, // pairs (indVar, value) of new bounds
413  newUB;
414 
415  delete [] a1;
416  delete [] a2;
417 
418 #ifdef DEBUG
419  printf (" ");
420  for (int j=0; j < n1; j++) printf ("x%d [%g,%g] ", ind1 [j], clb [ind1 [j]], cub [ind1 [j]]); printf ("--- ");
421  for (int j=0; j < n2; j++) printf ("x%d [%g,%g] ", ind2 [j], clb [ind2 [j]], cub [ind2 [j]]); printf ("\n");
422 #endif
423 
424  for (int i = 0; i < incnt; i++) {
425 
426  threshold *inalpha = inalphas [i];
427 
428 #ifdef DEBUG
429  printf (" looking at %d: (%d,%g,%s)\n", i,
430  inalphas [i] -> indVar,
431  inalphas [i] -> alpha,
432  (inalphas [i] -> sign == NEG) ? "NEG" :
433  (inalphas [i] -> sign == POS) ? "POS" :
434  (inalphas [i] -> sign == DN) ? "DN" : "UP");
435 
436  fflush (stdout);
437 #endif
438 
439  // look at each inalphas, those are the only breakpoints where
440  // bounds can improve. For alpha in {0,1} there is already a
441  // procedure (single constraint implied bound).
442 
443  // check for improved bounds at all variables
444 
445  double alpha = inalpha -> alpha;
446 
447  // enter next interval, update dynamic max/min sums for this
448  // value of alpha
449 
450  while (true) {
451 
452  inalpha = inalphas [i];
453 
454  int
455  signalpha = inalpha -> sign, // either UP or DN (not POS or NEG)
456  indVar = inalpha -> indVar; // the index of the variable whose a_i(alpha) changes sign
457 
458  double
459  clbi = clb [indVar],
460  cubi = cub [indVar];
461 
462  // as a variable is changing sign of (alpha a'_i + (1-alpha)
463  // a''_i), so must m[in|ax]Sum[12]
464 
465  if (fabs (clbi) > 0.) {
466 
467  if (clbi < - COUENNE_INFINITY/10) {
468 
469  if (signalpha == DN) {pInfs++; mInfs--;}
470  else {pInfs--; mInfs++;} // sign is UP
471 
472  } else {
473 
474  double
475  sa1ic = sa1 [indVar] * clbi,
476  sa2ic = sa2 [indVar] * clbi;
477 
478  if (signalpha == DN) { // means sa1 [indVar] < 0 while sa2 [indVar] > 0
479 
480  minSum1 -= sa1ic; minSum2 -= sa2ic;
481  maxSum1 += sa1ic; maxSum2 += sa2ic;
482 
483  } else { // sign must be UP
484 
485  minSum1 += sa1ic; minSum2 += sa2ic;
486  maxSum1 -= sa1ic; maxSum2 -= sa2ic;
487  }
488  }
489  }
490 
491  // same for upper bound
492 
493  if (fabs (cubi) > 0.) {
494 
495  if (cubi > COUENNE_INFINITY/10) {
496 
497  if (signalpha == DN) {pInfs--; mInfs++;}
498  else {pInfs++; mInfs--;} // sign is UP
499 
500  } else {
501 
502  double
503  sa1ic = sa1 [indVar] * cubi,
504  sa2ic = sa2 [indVar] * cubi;
505 
506  if (signalpha == DN) { // means sa1 [indVar] < 0 while sa2 [indVar] > 0
507 
508  minSum1 += sa1ic; minSum2 += sa2ic;
509  maxSum1 -= sa1ic; maxSum2 -= sa2ic;
510 
511  } else { // sign must be UP
512 
513  minSum1 -= sa1ic; minSum2 -= sa2ic;
514  maxSum1 += sa1ic; maxSum2 += sa2ic;
515  }
516  }
517  }
518 
519  if ((i < incnt-1) &&
520  (inalphas [i+1] -> alpha == alpha)) ++i;
521  else break;
522  }
523 
524 #ifdef DEBUG
525  printf (" at alpha=%g, m[in,ax]sum[12] = (1:(%g,%g), 2:(%g,%g)), %d mInf, %d pInf\n",
526  inalphas [i] -> alpha,
527  minSum1, maxSum1,
528  minSum2, maxSum2,
529  mInfs, pInfs);
530 #endif
531 
532  for (int j=0; j<n1+n2; j++) {
533 
534  // Loop on all variables that might improve a bound as a
535  // result of the convex combination with the current value of
536  // alpha.
537 
538  // scan all nonzeros, those on one side and those on both
539  // sides. This has already been scanned.
540  if (j >= n1 && sa1 [ind2 [j - n1]] != 0.)
541  continue;
542 
543  int
544  indVar = ((j < n1) ? ind1 [j] : ind2 [j - n1]),
545  tickMin = 0, // one if subtracting this term removes one infinity from minSum
546  tickMax = 0; // max
547 
548  double
549  sa1i = sa1 [indVar],
550  sa2i = sa2 [indVar],
551  ci = alpha * sa1i + (1. - alpha) * sa2i; // combination of coefficients
552 
553  // ignore variables whose coefficient is cancelled by this
554  // value of alpha
555 
556  if (fabs (ci) < MIN_DENOM)
557  continue;
558 
559  double
560  clbi = clb [indVar],
561  cubi = cub [indVar],
562 
563  newL = - COUENNE_INFINITY,
564  newU = COUENNE_INFINITY,
565 
566  subMin1 = 0., subMin2 = 0.,
567  subMax1 = 0., subMax2 = 0.;
568 
569 #ifdef DEBUG
570  printf (" now tightening x%d\n denominator: %g * %g + %g * %g = %g\n",
571  (j < n1) ? ind1 [j] : ind2 [j-n1],
572  alpha, sa1i, 1-alpha, sa2i, ci);
573 #endif
574 
575  // m[in,ax]Sum[1,2]A must be updated by subtracting the term
576  // that is now at the denominator (no need to multiply by
577  // signA, sa2 is already adjusted)
578 
579  if (clbi <= - COUENNE_INFINITY/10) {
580 
581  // we are deleting an infinite bound from the numerator, and
582  // whether it goes towards max- or min- Sum? depends on each
583  // coefficient
584 
585  if (ci > 0.) tickMin++;
586  else tickMax++;
587 
588  } else {
589 
590  if (ci > 0.) {
591 
592  subMin1 = sa1i * clbi;
593  subMin2 = sa2i * clbi;
594 
595  } else {
596 
597  subMax1 = sa1i * clbi;
598  subMax2 = sa2i * clbi;
599  }
600  }
601 
602  if (cubi >= COUENNE_INFINITY/10) {
603 
604  // we are deleting an infinite bound from the numerator, and
605  // whether it goes towards max- or min- Sum?A it depends on
606  // each coefficient
607 
608  if (ci > 0.) tickMax++;
609  else tickMin++;
610 
611  } else {
612 
613  if (ci > 0.) {
614 
615  subMax1 = sa1i * cubi;
616  subMax2 = sa2i * cubi;
617 
618  } else {
619 
620  subMin1 = sa1i * cubi;
621  subMin2 = sa2i * cubi;
622  }
623  }
624 
625  if (fabs (ci) < MIN_DENOM) { // must check that the numerator behaves
626 
627  } else {
628 
629  if ((l1 > -COUENNE_INFINITY/10) &&
630  (l2 > -COUENNE_INFINITY/10) &&
631  (pInfs == tickMax)) {
632 
633  newL = ((l1 - l2 - (maxSum1 - maxSum2) + (subMax1 - subMax2)) * alpha + l2 - maxSum2 + subMax2) / ci;
634 
635 #ifdef DEBUG
636  printf (" \
637 attempting newL = ((l1 - l2 - (maxSum1 - maxSum2) + (subMax1 - subMax2)) * alpha + l2 - maxSum2 + subMax2) / ci\n \
638 ((%g - %g - (%g - %g) + (%g - %g)) * %g + %g - %g + %g) / %g = %g\n",
639  l1, l2, maxSum1, maxSum2, subMax1, subMax2, alpha, l2, maxSum2, subMax2, ci, newL);
640 #endif
641  }
642 
643  if ((u1 < COUENNE_INFINITY/10) &&
644  (u2 < COUENNE_INFINITY/10) &&
645  (mInfs == tickMin)) {
646 
647  newU = ((u1 - u2 - (minSum1 - minSum2) + (subMin1 - subMin2)) * alpha + u2 - minSum2 + subMin2) / ci;
648 
649 #ifdef DEBUG
650  printf (" \
651 attempting newU = ((u1 - u2 - (minSum1 - minSum2) + (subMin1 - subMin2)) * alpha + u2 - minSum2 + subMin2) / ci\n \
652 ((%g - %g - (%g - %g) + (%g - %g)) * %g + %g - %g + %g) / %g = %g\n",
653  u1, u2, minSum1, minSum2, subMin1, subMin2, alpha, u2, minSum2, subMin2, ci, newU);
654 #endif
655  }
656 
657  if (ci < 0.) { // should have done the opposite assignment -- just swap them
658 
659 #ifdef DEBUG
660  printf (" swap'em: %g, %g\n", newL, newU);
661 #endif
662 
663  register double tmp = newL <= - COUENNE_INFINITY / 10 ? COUENNE_INFINITY : newL;
664  newL = newU >= COUENNE_INFINITY / 10 ? - COUENNE_INFINITY : newU;
665  newU = tmp;
666  }
667 
668 #ifdef DEBUG
669  printf (" final: %g, %g\n", newL, newU);
670 #endif
671  }
672 
673 #ifdef DEBUG
674  printf (" bounds for x_%d: [%g,%g] vs [%g,%g]\n", indVar, newL, newU, clb [indVar], cub [indVar]);
675 #endif
676 
677  if ((newL > cubi + COUENNE_EPS) ||
678  (newU < clbi - COUENNE_EPS)) {
679 
680  delete [] inalphas;
681  delete [] alphas;
682  delete [] ind1;
683  delete [] ind2;
684 
685 #ifdef DEBUG
686  printf ("infeasible\n");
687 #endif
688  return -1;
689  }
690 
691 #ifdef DEBUG
692  if (p -> bestSol () &&
693  ((p -> bestSol () [indVar] > newU + COUENNE_EPS) ||
694  (p -> bestSol () [indVar] < newL - COUENNE_EPS)) &&
695  (p -> bestSol () [indVar] >= clbi) &&
696  (p -> bestSol () [indVar] <= cubi))
697 
698  printf ("optimum violated: %g not in [%g,%g]\n", p -> bestSol () [indVar], newL, newU);
699 #endif
700 
701  double
702  &lbi = Lb [indVar],
703  &ubi = Ub [indVar];
704 
705  if ((newL > lbi + COUENNE_EPS) && (newL > -COUENNE_INFINITY / 10)) {
706 
707  ntightened++;
708  lbi = newL;
709  newLB. push_back (std::pair <int, double> (indVar, newL));
710 
711 #ifdef DEBUG
712  printf (" new lower bound: x%d >= %g [%g]\n", indVar, newL, clb [indVar]);
713 #endif
714  }
715 
716  if ((newU < ubi - COUENNE_EPS) && (newU < COUENNE_INFINITY / 10)) {
717 
718  ntightened++;
719  ubi = newU;
720  newUB. push_back (std::pair <int, double> (indVar, newU));
721 
722 #ifdef DEBUG
723  printf (" new upper bound: x%d <= %g [%g]\n", indVar, newU, cub [indVar]);
724 #endif
725  }
726  }
727  }
728 
729 #ifdef DEBUG
730  printf ("===================================\n");
731 #endif
732 
733  for (std::vector <std::pair <int, double> >::iterator i = newLB. begin (); i != newLB. end (); ++i) {
734 
735  if (isInteger [i -> first]) i -> second = ceil (i -> second - COUENNE_EPS);
736 
737  if (i -> second > clb [i -> first])
738  Lb [i -> first] = clb [i -> first] = i -> second;
739  }
740 
741  for (std::vector <std::pair <int, double> >::iterator i = newUB. begin (); i != newUB. end (); ++i) {
742 
743  if (isInteger [i -> first]) i -> second = floor (i -> second + COUENNE_EPS);
744 
745  if (i -> second < cub [i -> first])
746  Ub [i -> first] = cub [i -> first] = i -> second;
747  }
748 
749  delete [] inalphas;
750  delete [] alphas;
751 
752  delete [] ind1;
753  delete [] ind2;
754 
755  return ntightened;
756 }
757 
758 }
#define MIN_DENOM
static char * j
Definition: OSdtoa.cpp:3622
real alpha
int combine(CouenneProblem *p, int n1, int n2, const int *ind1, const int *ind2, double *sa1, double *sa2, const double *a1, const double *a2, double *clb, double *cub, double l1, double l2, double u1, double u2, bool *isInteger, int sign)
int compPair(register const void *p1, register const void *p2)
void fint fint fint real fint real real real real real real real real real * e
fint end
Class for MINLP problems with symbolic information.
#define COUENNE_EPS
int compthres(register const void *t1, register const void *t2)
double CouNumber
main number type in Couenne
#define COUENNE_INFINITY
bool isInteger(CouNumber x)
is this number integer?