genColCuts.cpp
Go to the documentation of this file.
1 /* $Id: genColCuts.cpp 810 2012-01-31 19:28:58Z pbelotti $
2  *
3  * Name: genColCuts.cpp
4  * Author: Pietro Belotti
5  * Purpose: generate Column Cuts for improved bounds
6  *
7  * (C) Carnegie-Mellon University, 2006-07.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include "CglCutGenerator.hpp"
12 #include "CouenneCutGenerator.hpp"
13 #include "CouenneProblem.hpp"
14 #include "CouenneExprVar.hpp"
15 
16 using namespace Couenne;
17 
18 //#define DEBUG
19 
21 void CouenneCutGenerator::genColCuts (const OsiSolverInterface &si,
22  OsiCuts &cs,
23  int nchanged,
24  int *changed) const {
25 
26 #ifdef DEBUG
27  int nrc = cs.sizeRowCuts ();// Must go
28 #endif
29 
30  int ncols = problem_ -> nVars (),
31  *indLow = new int [ncols], // indices for OsiColCut
32  *indUpp = new int [ncols], //
33  nLow, nUpp = nLow = 0;
34  //ind_obj = problem_ -> Obj (0) -> Body () -> Index ();
35 
36  // values fo OsiColCut
37  CouNumber *bndLow = new CouNumber [ncols],
38  *bndUpp = new CouNumber [ncols];
39 
40  const CouNumber
41  *oldLow = si.getColLower (), // old bounds
42  *oldUpp = si.getColUpper (),
43  *newLow = problem_ -> Lb (), // changed bounds
44  *newUpp = problem_ -> Ub ();
45 
46 #ifdef DEBUG
47  for (int i=0; i < problem_ -> nVars (); i++)
48  if ((newLow [i] > oldLow [i] + COUENNE_EPS) ||
49  (newUpp [i] < oldUpp [i] - COUENNE_EPS))
50  printf ("x%-3d. [%-10g , %10g] ---> [%-10g , %10g]\n",
51  i, oldLow [i], oldUpp [i], newLow [i], newUpp [i]);
52 #endif
53 
54  // check all changed bounds
55  for (int i = 0; i < nchanged; i++) {
56 
57  int index = changed [i];
58 
59  // fails with spectra2 with (abt=2,obbt=0) for variable x70
60  //assert (problem_ -> Var (index) -> Multiplicity () > 0);
61 
62  if (//(index == ind_obj) ||
63  (problem_ -> Var (index) -> Multiplicity () <= 0))
64  continue;
65 
66  if (newLow [index] > newUpp [index])
67  problem_ -> Lb (index) = problem_ -> Ub (index);
68 
69  CouNumber bd;
70 
71  if ((((bd = newLow [index]) > oldLow [index] + COUENNE_EPS) || firstcall_) // better lb?
72  && (bd > -COUENNE_INFINITY / 10)) { // finite?
73 
74  //printf ("chging low %d %g -> %g\n", index, oldLow [index], newLow [index]);
75  if (problem_ -> Var (index) -> isInteger ())
76  bd = ceil (bd - COUENNE_EPS);
77  indLow [nLow] = index;
78  bndLow [nLow++] = bd;
79  }
80 
81  if ((((bd = newUpp [index]) < oldUpp [index] - COUENNE_EPS) || firstcall_) // better ub?
82  && (bd < COUENNE_INFINITY / 10)) { // finite?
83 
84  //printf ("chging upp %d %g -> %g\n", index, oldUpp [index], newUpp [index]);
85  if (problem_ -> Var (index) -> isInteger ())
86  bd = floor (bd + COUENNE_EPS);
87  indUpp [nUpp] = index;
88  bndUpp [nUpp++] = bd;
89  }
90  }
91 
92  // create Column Cut
93 
94  if (nUpp || nLow) {
95 
96  OsiColCut *cut = new OsiColCut;
97 
98  if (cut) {
99  cut -> setLbs (nLow, indLow, bndLow);
100  cut -> setUbs (nUpp, indUpp, bndUpp);
101 
102  cs.insert (cut);
103  delete cut;
104  }
105  }
106 
107 #ifdef DEBUG
108  printf ("column cuts\n");
109  for (int jj = nrc; jj < cs.sizeRowCuts (); jj++) cs.rowCutPtr (jj) -> print ();
110 #endif
111 
112  delete [] bndLow; delete [] indLow;
113  delete [] bndUpp; delete [] indUpp;
114 }
bool firstcall_
True if no convexification cuts have been generated yet for this problem.
#define COUENNE_EPS
double CouNumber
main number type in Couenne
#define COUENNE_INFINITY
CouenneProblem * problem_
pointer to symbolic repr. of constraint, variables, and bounds
void genColCuts(const OsiSolverInterface &, OsiCuts &, int, int *) const
generate OsiColCuts for improved (implied and propagated) bounds
Definition: genColCuts.cpp:21
bool isInteger(CouNumber x)
is this number integer?