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

Go to the documentation of this file.
00001 /* $Id: conv-exprDiv.cpp 141 2009-06-03 04:19:19Z pbelotti $ */
00002 /*
00003  * Name:    conv-exprDiv.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: standardization and convexification methods for divisions
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 "expression.hpp"
00013 #include "exprAux.hpp"
00014 #include "exprOp.hpp"
00015 #include "exprDiv.hpp"
00016 #include "exprClone.hpp"
00017 #include "exprMul.hpp"
00018 #include "CouenneProblem.hpp"
00019 #include "CouenneCutGenerator.hpp"
00020 
00021 
00022 // Create standard formulation of this expression
00023 exprAux *exprDiv::standardize (CouenneProblem *p, bool addAux) {
00024 
00025   exprOp::standardize (p);
00026   return (addAux ? (p -> addAuxiliary (this)) : new exprAux (this, p -> domain ()));
00027 }
00028 
00029 
00030 // generate convexification cut for constraint w = x/y
00031 void exprDiv::generateCuts (expression *w, const OsiSolverInterface &si, 
00032                             OsiCuts &cs, const CouenneCutGenerator *cg,
00033                             t_chg_bounds *chg, int wind, 
00034                             CouNumber lbw, CouNumber ubw) {
00035   // compute y bounds
00036 
00037   CouNumber yl, yu;
00038   arglist_ [1] -> getBounds (yl, yu);
00039 
00040   int xi = arglist_ [0] -> Index (),
00041       yi = arglist_ [1] -> Index (),
00042       wi = w            -> Index ();
00043 
00044   bool cLW,  cRW,  cLY,  cRY = 
00045        cLW = cRW = cLY = true;
00046 
00047   if (!(cg -> isFirst ()) && chg) {
00048     cLW = chg [wi].lower() != t_chg_bounds::UNCHANGED;
00049     cRW = chg [wi].upper() != t_chg_bounds::UNCHANGED;
00050     cLY = chg [yi].lower() != t_chg_bounds::UNCHANGED;
00051     cRY = chg [yi].upper() != t_chg_bounds::UNCHANGED;
00052   }
00053 
00054   if ((yl < -0) && (yu > 0)) return;   // no convexification
00055 
00056   // special case #1: y is almost constant (nonzero) --> y = k. We
00057   // only need a single plane w = x/k.
00058 
00059   CouNumber k;
00060 
00061   if ((fabs (yl-yu) < COUENNE_EPS) && 
00062       ((fabs (k = ((yl+yu) / 2)) > COUENNE_EPS))) {
00063     if (cLY || cRY)
00064       cg -> createCut (cs, 0., 0, wi, -1, xi, 1/k);
00065     return;
00066   }
00067 
00068   CouNumber wl, wu;
00069   w -> getBounds (wl, wu);
00070 
00071   if (lbw > wl) wl = lbw;
00072   if (ubw < wu) wu = ubw;
00073 
00074   // special case #2: w is almost constant (nonzero) --> w = x/y = k. We
00075   // only need a single plane x = y*k.
00076 
00077   if ((fabs (wl-wu) < COUENNE_EPS) &&
00078       ((k = fabs (wl+wu) / 2) > COUENNE_EPS)) {
00079     if (cLW || cRW)
00080       cg -> createCut (cs, 0., 0, yi, k, xi, -1.);
00081     return;
00082   }
00083 
00084   CouNumber xl, xu;
00085   arglist_ [0] -> getBounds (xl, xu);
00086 
00087   // same as product, just a change in coordinates
00088 
00089   //CouNumber *x = w -> domain () -> x ();
00090   CouNumber *x = cg -> Problem () -> X ();
00091 
00092   unifiedProdCuts (cg, cs,
00093                    wi, x [wi], wl, wu,
00094                    yi, x [yi], yl, yu,
00095                    xi, x [xi], xl, xu, chg);
00096 
00097   // TODO: put real convexification...
00098 }

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