separateWithDisjunction.cpp
Go to the documentation of this file.
1 /* $Id: separateWithDisjunction.cpp 694 2011-06-18 20:13:17Z stefan $
2  *
3  * Name: separateWithDisjunction.cpp
4  * Author: Pietro Belotti
5  * Purpose: generate cuts of disjunction
6  *
7  * (C) Carnegie-Mellon University, 2008.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include "CouennePrecisions.hpp"
12 #include "CouenneDisjCuts.hpp"
13 #include "CouenneCutGenerator.hpp"
14 #include "CouenneProblem.hpp"
15 
16 using namespace Ipopt;
17 using namespace Couenne;
18 
20 int CouenneDisjCuts::separateWithDisjunction (OsiCuts *cuts,
21  OsiSolverInterface &si,
22  OsiCuts &cs,
23  const CglTreeInfo &info) const {
24 
25  if (jnlst_ -> ProduceOutput (J_VECTOR, J_DISJCUTS) &&
26  ((cuts -> sizeRowCuts ()) ||
27  (cuts -> sizeColCuts ()))) {
28 
29  printf ("applying unilateral cuts:\n");
30 
31  if (cuts -> sizeRowCuts ()) {
32  printf ("Row\n");
33  for (int i=0; i < cuts -> sizeRowCuts (); i++) cuts -> rowCutPtr (i) -> print ();
34  }
35 
36  if (cuts -> sizeColCuts ()) {
37  printf (" Col\n");
38  for (int i=0; i < cuts -> sizeColCuts (); i++) cuts -> colCutPtr (i) -> print ();
39  }
40  }
41 
42  int ncols = si.getNumCols ();
43  t_chg_bounds *chg = new t_chg_bounds [ncols]; // all init'd automatically to UNCHANGED
44  CouenneProblem *p = couenneCG_ -> Problem ();
45 
46  p -> domain () -> push (&si);
47 
48  // apply cuts
49  for (int i = cuts -> sizeColCuts (); i--;) {
50 
51  const CoinPackedVector
52  &lb = cuts -> colCutPtr (i) -> lbs (),
53  &ub = cuts -> colCutPtr (i) -> ubs ();
54 
55  const int
56  *lind = lb.getIndices (),
57  *uind = ub.getIndices ();
58 
59  const double
60  *lval = lb.getElements (), *oLB = si.getColLower (),
61  *uval = ub.getElements (), *oUB = si.getColUpper ();
62 
63  for (int j=lb.getNumElements (); j--; lind++, lval++)
64  if (*lval > oLB [*lind] + COUENNE_EPS) {
65  p -> Lb (*lind) = *lval;
66  chg [*lind].setLower (t_chg_bounds::CHANGED);
67  }
68 
69  for (int j=ub.getNumElements (); j--; uind++, uval++)
70  if (*uval < oUB [*uind] - COUENNE_EPS) {
71  p -> Ub (*uind) = *uval;
72  chg [*uind].setUpper (t_chg_bounds::CHANGED);
73  }
74  }
75 
76  int *changed = NULL, // will be created within sparse2dense
77  nchanged = 0;
78 
79  sparse2dense (ncols, chg, changed, nchanged);
80 
81  couenneCG_ -> genRowCuts (si, *cuts, nchanged, changed, chg);
82 
83  p -> domain () -> pop ();
84 
85  delete [] chg;
86 
87  if (changed)
88  free (changed);
89 
90  return COUENNE_FEASIBLE;
91 }
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real fint fint fint fint * info
status of lower/upper bound of a variable, to be checked/modified in bound tightening ...
void setLower(ChangeStatus lower)
void sparse2dense(int ncols, t_chg_bounds *chg_bds, int *&changed, int &nchanged)
translate sparse to dense vector (should be replaced)
const Ipopt::EJournalCategory J_DISJCUTS(Ipopt::J_USER6)
static char * j
Definition: OSdtoa.cpp:3622
void setUpper(ChangeStatus upper)
Class for MINLP problems with symbolic information.
#define COUENNE_EPS