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

Go to the documentation of this file.
00001 /* $Id: conv-exprMul-genCuts.cpp 490 2011-01-14 16:07:12Z 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-10.
00008  * This file is licensed under the Eclipse Public License (EPL)
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   // if expression is x*c or c*y, with c constant from the problem
00035   // definition or from the branching rules, the expression is
00036   // linear. Add one convexification equality constraint.
00037 
00038   // check if either operand is constant
00039 
00040   bool is0const = (xe -> Type () == CONST),
00041        is1const = (ye -> Type () == CONST);
00042 
00043   CouNumber c0=0, c1=0;
00044 
00045   // is one of the two constant?
00046 
00047   if (is0const) c0 = xe -> Value ();  
00048   if (is1const) c1 = ye -> Value ();  
00049 
00050   // compute bounds
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   // check if either operator got constant because of the branching
00062   // rules: 
00063 
00064   bool i0s, i1s = i0s = false;
00065 
00066   // TODO: Fix this!
00067 
00068   // x...
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   // ...and y
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   // right now c0 and c1 only have a value if the corresponding
00094   // expression is constant
00095 
00096   if (is0const || is1const) {
00097 
00098     if (cg -> isFirst () ||            // if first call or
00099         ((xe -> Type () != CONST) &&   // neither term is a defined constant
00100          (ye -> Type () != CONST))) {  // (=> implied by branching rule)
00101 
00102       if (is0const && is1const)
00103         // w = c0*c1, which is either because the intervals got very
00104         // narrow, or because these are indeed constant (which should
00105         // have been dealt with in simplify(), but who knows...)
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;} // c*y
00114         else          {coe = c1; ind = xi;} // x*c
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   // add different cuts, to cut out current point in bounding box but
00126   // out of the hyperbola's belly
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                    //sign == expression::AUX_LEQ ? -COIN_DBL_MAX : wl, 
00136                    //sign == expression::AUX_GEQ ?  COIN_DBL_MAX : wu,
00137                    chg, sign);
00138 }

Generated on Thu Nov 10 03:05:43 2011 by  doxygen 1.4.7