00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CouennePrecisions.hpp"
00012 #include "CouenneDisjCuts.hpp"
00013 #include "CouenneCutGenerator.hpp"
00014 #include "CouenneProblem.hpp"
00015
00016 using namespace Ipopt;
00017 using namespace Couenne;
00018
00020 int CouenneDisjCuts::separateWithDisjunction (OsiCuts *cuts,
00021 OsiSolverInterface &si,
00022 OsiCuts &cs,
00023 const CglTreeInfo &info) const {
00024
00025 if (jnlst_ -> ProduceOutput (J_VECTOR, J_DISJCUTS) &&
00026 ((cuts -> sizeRowCuts ()) ||
00027 (cuts -> sizeColCuts ()))) {
00028
00029 printf ("applying unilateral cuts:\n");
00030
00031 if (cuts -> sizeRowCuts ()) {
00032 printf ("Row\n");
00033 for (int i=0; i < cuts -> sizeRowCuts (); i++) cuts -> rowCutPtr (i) -> print ();
00034 }
00035
00036 if (cuts -> sizeColCuts ()) {
00037 printf (" Col\n");
00038 for (int i=0; i < cuts -> sizeColCuts (); i++) cuts -> colCutPtr (i) -> print ();
00039 }
00040 }
00041
00042 int ncols = si.getNumCols ();
00043 t_chg_bounds *chg = new t_chg_bounds [ncols];
00044 CouenneProblem *p = couenneCG_ -> Problem ();
00045
00046 p -> domain () -> push (&si);
00047
00048
00049 for (int i = cuts -> sizeColCuts (); i--;) {
00050
00051 const CoinPackedVector
00052 &lb = cuts -> colCutPtr (i) -> lbs (),
00053 &ub = cuts -> colCutPtr (i) -> ubs ();
00054
00055 const int
00056 *lind = lb.getIndices (),
00057 *uind = ub.getIndices ();
00058
00059 const double
00060 *lval = lb.getElements (), *oLB = si.getColLower (),
00061 *uval = ub.getElements (), *oUB = si.getColUpper ();
00062
00063 for (int j=lb.getNumElements (); j--; lind++, lval++)
00064 if (*lval > oLB [*lind] + COUENNE_EPS) {
00065 p -> Lb (*lind) = *lval;
00066 chg [*lind].setLower (t_chg_bounds::CHANGED);
00067 }
00068
00069 for (int j=ub.getNumElements (); j--; uind++, uval++)
00070 if (*uval < oUB [*uind] - COUENNE_EPS) {
00071 p -> Ub (*uind) = *uval;
00072 chg [*uind].setUpper (t_chg_bounds::CHANGED);
00073 }
00074 }
00075
00076 int *changed = NULL,
00077 nchanged = 0;
00078
00079 sparse2dense (ncols, chg, changed, nchanged);
00080
00081 couenneCG_ -> genRowCuts (si, *cuts, nchanged, changed, chg);
00082
00083 p -> domain () -> pop ();
00084
00085 delete [] chg;
00086
00087 if (changed)
00088 free (changed);
00089
00090 return COUENNE_FEASIBLE;
00091 }