00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "OsiSolverInterface.hpp"
00012 #include "CouenneTypes.hpp"
00013 #include "CouenneCutGenerator.hpp"
00014 #include "exprAbs.hpp"
00015 #include "exprAux.hpp"
00016
00017
00018
00019
00020 void exprAbs::generateCuts (expression *w,
00021 OsiCuts &cs, const CouenneCutGenerator *cg,
00022 t_chg_bounds *chg, int wind,
00023 CouNumber lbw, CouNumber ubw) {
00024
00025 int w_ind = w -> Index (),
00026 x_ind = argument_ -> Index ();
00027
00028 CouNumber l, u;
00029 argument_ -> getBounds (l, u);
00030
00031 bool
00032 cbase = !chg || cg -> isFirst (),
00033 cLeft = cbase || (chg [x_ind].lower() != t_chg_bounds::UNCHANGED),
00034 cRight = cbase || (chg [x_ind].upper() != t_chg_bounds::UNCHANGED);
00035
00036
00037
00038 if (l >= -0) {if (cLeft) cg -> createCut (cs, 0., 0, w_ind, 1., x_ind, -1.);}
00039 else if (u <= 0) {if (cRight) cg -> createCut (cs, 0., 0, w_ind, 1., x_ind, +1.);}
00040 else {
00041
00042
00043 if (cg -> isFirst ()) {
00044 cg -> createCut (cs, 0., +1, w_ind, 1., x_ind, -1.);
00045 cg -> createCut (cs, 0., +1, w_ind, 1., x_ind, 1.);
00046 }
00047
00048
00049
00050
00051
00052 if (l > - COUENNE_INFINITY) {
00053 if (u < COUENNE_INFINITY) {
00054
00055 CouNumber slope = (u+l) / (u-l);
00056
00057
00058 if (cLeft || cRight)
00059 cg -> createCut (cs, -l*(slope+1.), -1, w_ind, 1., x_ind, -slope);
00060 }
00061 else
00062 if (cLeft) cg -> createCut (cs, -2*l, -1, w_ind, 1., x_ind, -1.);
00063 }
00064 else if (u < COUENNE_INFINITY)
00065 if (cRight) cg -> createCut (cs, 2*u, -1, w_ind, 1., x_ind, 1.);
00066 }
00067 }