00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CouenneCutGenerator.hpp"
00012
00013 #include "CouenneTypes.hpp"
00014 #include "CouenneExprSub.hpp"
00015 #include "CouenneExprOpp.hpp"
00016 #include "CouenneExprAux.hpp"
00017
00018 using namespace Couenne;
00019
00020
00021 void exprSub::generateCuts (expression *w,
00022 OsiCuts &cs, const CouenneCutGenerator *cg,
00023 t_chg_bounds *chg,
00024 int wind, CouNumber lb, CouNumber ub) {
00025
00026 if (!(cg -> isFirst ()))
00027 return;
00028
00029
00030
00031 expression *x = arglist_ [0];
00032 expression *y = arglist_ [1];
00033
00034 int wi = w -> Index ();
00035 int xi = x -> Index ();
00036 int yi = y -> Index ();
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 CouNumber vlb, vub;
00047 w -> getBounds (vlb, vub);
00048 bool uselessAux = (vub < vlb + COUENNE_EPS);
00049
00050
00051
00052 if ((wind >= 0) || uselessAux) {
00053 wi = -1;
00054 lb = ub = vlb;
00055 }
00056 else lb = ub = 0;
00057
00058 if (xi < 0) {
00059 CouNumber x0 = x -> Value ();
00060 lb -= x0;
00061 ub -= x0;
00062 }
00063
00064 if (yi < 0) {
00065 CouNumber y0 = y -> Value ();
00066 lb += y0;
00067 ub += y0;
00068 }
00069
00070 enum auxSign sign = cg -> Problem () -> Var (w -> Index ()) -> sign ();
00071
00072 if (sign == expression::AUX_GEQ) lb = -COIN_DBL_MAX;
00073 else if (sign == expression::AUX_LEQ) ub = COIN_DBL_MAX;
00074
00075 cg -> createCut (cs, lb, ub, wi, -1., xi, 1., yi, -1., true);
00076 }