00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CouenneCutGenerator.hpp"
00012
00013 #include "CouenneTypes.hpp"
00014 #include "CouenneExprMul.hpp"
00015 #include "CouenneProblem.hpp"
00016 #include "CouenneExprAux.hpp"
00017
00018 using namespace Couenne;
00019
00021
00022 void exprMul::generateCuts (expression *w,
00023 OsiCuts &cs, const CouenneCutGenerator *cg,
00024 t_chg_bounds *chg, int wind,
00025 CouNumber lbw, CouNumber ubw) {
00026
00027 expression *xe = arglist_ [0];
00028 expression *ye = arglist_ [1];
00029
00030 int wi = w -> Index (),
00031 xi = xe -> Index (),
00032 yi = ye -> Index ();
00033
00034
00035
00036
00037
00038
00039
00040 bool is0const = (xe -> Type () == CONST),
00041 is1const = (ye -> Type () == CONST);
00042
00043 CouNumber c0=0, c1=0;
00044
00045
00046
00047 if (is0const) c0 = xe -> Value ();
00048 if (is1const) c1 = ye -> Value ();
00049
00050
00051
00052 CouNumber xl, xu, yl, yu, wl, wu;
00053
00054 xe -> getBounds (xl, xu);
00055 ye -> getBounds (yl, yu);
00056 w -> getBounds (wl, wu);
00057
00058 if (lbw > wl) wl = lbw;
00059 if (ubw < wu) wu = ubw;
00060
00061
00062
00063
00064 bool i0s, i1s = i0s = false;
00065
00066
00067
00068
00069
00070 if (!is0const && ((xu-xl) < COUENNE_EPS)) {
00071
00072 if (is1const) i0s = (fabs (c1) * (xu-xl) < COUENNE_EPS);
00073 else i0s = ((fabs (yu) + fabs (yl)) * (xu-xl) < COUENNE_EPS);
00074
00075 if (i0s)
00076 c0 = 0.5 * (xl+xu);
00077 }
00078
00079
00080
00081 if (!is1const && ((yu-yl) < COUENNE_EPS)) {
00082
00083 if (is0const) i1s = (fabs (c0) * (yu-yl) < COUENNE_EPS);
00084 else i1s = ((fabs (xu) + fabs (xl)) * (yu-yl) < COUENNE_EPS);
00085
00086 if (i1s)
00087 c1 = 0.5 * (yl+yu);
00088 }
00089
00090 if (i0s) is0const = true;
00091 if (i1s) is1const = true;
00092
00093
00094
00095
00096 if (is0const || is1const) {
00097
00098 if (cg -> isFirst () ||
00099 ((xe -> Type () != CONST) &&
00100 (ye -> Type () != CONST))) {
00101
00102 if (is0const && is1const)
00103
00104
00105
00106 cg -> createCut (cs, c0 * c1, cg -> Problem () -> Var (wi) -> sign (), wi, 1.);
00107
00108 else {
00109
00110 CouNumber coe;
00111 int ind;
00112
00113 if (is0const) {coe = c0; ind = yi;}
00114 else {coe = c1; ind = xi;}
00115
00116 cg -> createCut (cs, 0., cg -> Problem () -> Var (wi) -> sign (), wi, 1., ind, -coe);
00117 }
00118 }
00119
00120 return;
00121 }
00122
00123 enum auxSign sign = cg -> Problem () -> Var (wi) -> sign ();
00124
00125
00126
00127
00128 CouNumber x0 = (*(arglist_ [0])) (),
00129 y0 = (*(arglist_ [1])) ();
00130
00131 unifiedProdCuts (cg, cs,
00132 xi, x0, xl, xu,
00133 yi, y0, yl, yu,
00134 wi, (*w) (), wl, wu,
00135
00136
00137 chg, sign);
00138 }