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