/home/coin/SVN-release/OS-2.0.0/Couenne/src/convex/operators/conv-exprMul-genCuts.cpp

Go to the documentation of this file.
00001 /* $Id: conv-exprMul-genCuts.cpp 141 2009-06-03 04:19:19Z pbelotti $ */
00002 /*
00003  * Name:    conv-exprMul-genCuts.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: method to convexify multiplications
00006  *
00007  * (C) Carnegie-Mellon University, 2006. 
00008  * This file is licensed under the Common Public License (CPL)
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   // if expression is x*c or c*y, with c constant from the problem
00031   // definition or from the branching rules, the expression is
00032   // linear. Add one convexification equality constraint.
00033 
00034   // check if either operand is constant
00035 
00036   bool is0const = (xe -> Type () == CONST),
00037        is1const = (ye -> Type () == CONST);
00038 
00039   CouNumber c0=0, c1=0;
00040 
00041   // is one of the two constant?
00042 
00043   if (is0const) c0 = xe -> Value ();  
00044   if (is1const) c1 = ye -> Value ();  
00045 
00046   // compute bounds
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   // check if either operator got constant because of the branching
00058   // rules: 
00059 
00060   bool i0s, i1s = i0s = false;
00061 
00062   // TODO: Fix this!
00063 
00064   // x...
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   // ...and y
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   // right now c0 and c1 only have a value if the corresponding
00090   // expression is constant
00091 
00092   if (is0const || is1const) {
00093 
00094     if (cg -> isFirst () ||            // if first call or
00095         ((xe -> Type () != CONST) &&   // neither term is a defined constant
00096          (ye -> Type () != CONST))) {  // (=> implied by branching rule)
00097 
00098       if (is0const && is1const)
00099         // w = c0*c1, which is either because the intervals got very
00100         // narrow, or because these are indeed constant (which should
00101         // have been dealt with in simplify(), but who knows...)
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;} // c*y
00110         else          {coe = c1; ind = xi;} // x*c
00111 
00112         cg -> createCut (cs, 0., 0, wi, -1., ind, coe);
00113       }
00114     }
00115 
00116     return;
00117   }
00118 
00119   // add different cuts, to cut out current point in bounding box but
00120   // out of the hyperbola's belly
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 }

Generated on Mon Aug 3 03:02:19 2009 by  doxygen 1.4.7