00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CouenneCutGenerator.hpp"
00012
00013 #include "CouenneTypes.hpp"
00014
00015 #include "CouenneExprAux.hpp"
00016 #include "CouenneExprSum.hpp"
00017 #include "CouenneExprConst.hpp"
00018
00019 #include "CouenneProblem.hpp"
00020
00021 using namespace Couenne;
00022
00023
00024 void exprSum::generateCuts (expression *w,
00025 OsiCuts &cs, const CouenneCutGenerator *cg,
00026 t_chg_bounds *chg,
00027 int wind, CouNumber lb, CouNumber ub) {
00028 if (!(cg -> isFirst ()))
00029 return;
00030
00031 CouNumber *coeff = new CouNumber [nargs_ + 1];
00032 int *index = new int [nargs_ + 1];
00033 OsiRowCut *cut = new OsiRowCut;
00034
00036
00037 int nv = 0;
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 CouNumber vlb, vub;
00048 w -> getBounds (vlb, vub);
00049 bool uselessAux = (vub < vlb + COUENNE_EPS);
00050
00051
00052
00053 if (wind < 0 && !uselessAux) {
00054 coeff [0] = -1.; index [0] = w -> Index ();
00055 nv++;
00056 lb = ub = 0;
00057 }
00058
00059 if (uselessAux)
00060 lb = ub = vlb;
00061
00063 for (int i=0; i<nargs_; i++) {
00064
00065 if (arglist_ [i] -> Type () == CONST) {
00066
00067 CouNumber val = arglist_ [i] -> Value ();
00068
00069 lb -= val;
00070 ub -= val;
00071 }
00072 else {
00073 coeff [nv] = 1.;
00074 index [nv++] = arglist_ [i] -> Index ();
00075 }
00076 }
00077
00078 cut -> setRow (nv, index, coeff);
00079
00080 delete [] index;
00081 delete [] coeff;
00082
00083 enum auxSign sign = cg -> Problem () -> Var (w -> Index ()) -> sign ();
00084
00085 if (lb > -COUENNE_INFINITY && (sign != expression::AUX_GEQ)) cut -> setLb (lb);
00086 if (ub < COUENNE_INFINITY && (sign != expression::AUX_LEQ)) cut -> setUb (ub);
00087
00089 cut -> setGloballyValid ();
00090
00091 cs.insert (cut);
00092 delete cut;
00093 }