1 /* $Id$
2 *
3 * Name: CouenneLPtightenBounds.cpp
4 * Authors: Pietro Belotti, Carnegie Mellon University
5 * Purpose: tighten LP bounds on all variables (including continuous)
6 *
7 * (C) Carnegie-Mellon University, 2008-09.
8 * This file is licensed under the Eclipse Public License (EPL)
9 */
10
11 #include "CouenneProblem.hpp"
12 #include "CouenneCutGenerator.hpp"
13
14 namespace Couenne {
15
16 // Tighten bounds - lightweight. Returns -1 if infeasible, otherwise
17 // number of variables tightened.
18 template <class T>
tightenBounds(int lightweight)19 int CouenneSolverInterface<T>::tightenBounds (int lightweight) {
20
21 if (!(cutgen_ -> enableLpImpliedBounds ()))
22 return 0;
23
24 int
25 ncols = T::getNumCols (),
26 nTightened;
27
28 double
29 *oldLower = new double [ncols],
30 *oldUpper = new double [ncols];
31
32 CoinCopyN (T::getColLower (), ncols, oldLower);
33 CoinCopyN (T::getColUpper (), ncols, oldUpper);
34
35 // printf ("-------- BOUNDS BEFORE ------------\n ");
36 // int j=0;
37 // for (int i=0; i < ncols; i++) {
38 // printf("x_%03d [%+15.8g %+15.8g] ", i, oldLower [i], oldUpper [i]);
39 // if (!(++j % 6)) printf ("\n ");
40 // }
41 // if (j % 6) printf ("\n");
42
43 nTightened = tightenBoundsCLP (lightweight);
44
45 if (nTightened < 0)
46 return nTightened;
47
48 // printf ("-------- BOUNDS DURING ------------\n ");
49 // j=0;
50 // for (int i=0; i < ncols; i++) {
51 // printf("x_%03d [%+15.8g %+15.8g] ", i, getColLower () [i], getColUpper () [i]);
52 // if (!(++j % 6)) printf ("\n ");
53 // }
54 // if (j % 6) printf ("\n");
55
56 if (nTightened > 0) {
57
58 // something was tightened. Run an extra btCore "por si las
59 // moscas" (just in case)
60
61 const double
62 *newLower = T::getColLower (),
63 *newUpper = T::getColUpper ();
64
65 t_chg_bounds *chgd = new t_chg_bounds [ncols];
66
67 for (int i=0; i<ncols; i++) {
68 if (newLower [i] > oldLower [i] + COUENNE_EPS) chgd [i].setLower (t_chg_bounds::CHANGED);
69 if (newUpper [i] < oldUpper [i] - COUENNE_EPS) chgd [i].setUpper (t_chg_bounds::CHANGED);
70 }
71
72 cutgen_ -> Problem () -> domain () -> push (ncols, NULL, newLower, newUpper);
73
74 if (!(cutgen_ -> Problem () -> btCore (chgd))) // infeasible
75 nTightened = -1;
76
77 else {
78
79 const double
80 *newerLower = cutgen_ -> Problem () -> Lb (),
81 *newerUpper = cutgen_ -> Problem () -> Ub ();
82
83 for (int i=0; i<ncols; i++) {
84
85 if (newerLower [i] > newLower [i] + COUENNE_EPS) {
86 T::setColLower (i, newerLower [i]);
87 if (newLower [i] < oldLower [i] + COUENNE_EPS) nTightened++; // extra tightening
88 }
89
90 if (newerUpper [i] < newUpper [i] - COUENNE_EPS) {
91 T::setColUpper (i, newerUpper [i]);
92 if (newUpper [i] > oldUpper [i] - COUENNE_EPS) nTightened++; // extra tightening
93 }
94 }
95 }
96
97 // const double
98 // *newerLower = cutgen_ -> Problem () -> Lb (),
99 // *newerUpper = cutgen_ -> Problem () -> Ub ();
100
101 // printf ("-------- BOUNDS AFTER ------------\n ");
102 // for (int i=0; i < ncols; i++) {
103 // printf("x_%03d [%+15.8g %+15.8g] ", i, newerLower [i], newerUpper [i]);
104 // if (!(++j % 6)) printf ("\n ");
105 // }
106 // if (j % 6) printf ("\n");
107
108 cutgen_ -> Problem () -> domain () -> pop ();
109
110 delete [] chgd;
111 }
112
113 delete [] oldLower;
114 delete [] oldUpper;
115
116 return nTightened;
117 }
118
119 }
120