/home/coin/SVN-release/OS-2.4.2/Couenne/src/branch/operators/computeMulBrDist.cpp

Go to the documentation of this file.
00001 /* $Id: computeMulBrDist.cpp 490 2011-01-14 16:07:12Z pbelotti $
00002  *
00003  * Name:    computeMulBrDist.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: compute distance to new convexifications generated by branching on product
00006  *
00007  * (C) Carnegie-Mellon University, 2008-10.
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include "CouennePrecisions.hpp"
00012 #include "CouenneTypes.hpp"
00013 #include "CouenneObject.hpp"
00014 
00015 #include "CouenneExprMul.hpp"
00016 #include "CouenneFunTriplets.hpp"
00017 #include "CouenneProjections.hpp"
00018 
00019 namespace Couenne {
00020 
00021 // compute distance from future convexifications in set \f$\{(x,y,w):
00022 // w = xy\}\f$ with x,y,w bounded
00023 double *computeMulBrDist (const OsiBranchingInformation *info,
00024                           int xi, int yi, int wi, 
00025                           int brind, double *brpt, int nPts) {
00026 
00027   // use rule of thumb to compute distance: fix two of the three
00028   // variables and compute distance between current LP point and curve
00029   // w=x/y (z is the branching variable, x or y)
00030   //
00031   // 1) fix x,y: distances are w - x/y and ||(w-x/y, z-zb)||_2 
00032   // 2) fix x,w:               y - x/w and ||(y-x/w, z-zb)||_2
00033   // 3) fix y,w:               x - y*w and ||(x-y*w, z-zb)||_2
00034 
00035   CouNumber 
00036     x0 = info -> solution_ [xi], //xl = info -> lower_ [xi], xu = info -> upper_ [xi],
00037     y0 = info -> solution_ [yi], //yl = info -> lower_ [yi], yu = info -> upper_ [yi],
00038     w0 = info -> solution_ [wi]; //wl = info -> lower_ [wi], wu = info -> upper_ [wi];
00039 
00040   double *dist = (double *) malloc (2 * sizeof (double));
00041 
00042   // two main cases: 
00043   //
00044   // 1) wi is the branching index: the bounding box is divided in two
00045   // by the rule w <= wb and w >= wb. Finding the distances from the
00046   // current point (x0,y0,w0) to the two semi-surfaces depends on
00047   // which side w0 stands.
00048   //
00049   // 2) xi or yi are the branching index: reduce to the problem of
00050   // finding the distance from a point (x0,y0,w0) to the same surface
00051   // within the (two) element of a partition of the bounding box.
00052 
00053 
00054   // case 1 ////////////////////////////////////////////////////////////////////
00055   //
00056   // Depending on whether
00057   //
00058   // a) w0 <=/>= wb
00059   // b) w0 <=/>= x0*y0
00060   // c) wb <=/>= 0
00061   //
00062   // there are eight (!) cases, each with a similar computation for
00063   // the two distances. We unify it below.
00064 
00065   // [for now give a simplified version with rough distance computation]
00066 
00067   if (brind == wi) {
00068 
00069     // easy implementation: for own side, w0 - x0 y0; for other side,
00070     // horiz/vert distance to curve x0 w0 = wb
00071 
00072     bool side = (((x0*y0 > *brpt) && (*brpt > 0)) ||
00073                  ((x0*y0 < *brpt) && (*brpt < 0)));
00074 
00075     dist [side ? 1 : 0] = CoinMax 
00076       (fabs (w0 - x0*y0), CoinMin 
00077        ((fabs (y0) > COUENNE_EPS) ? fabs (x0 - *brpt / y0) : 0.,
00078         (fabs (x0) > COUENNE_EPS) ? fabs (y0 - *brpt / x0) : 0.));
00079 
00080     dist [side ? 0 : 1] = fabs (w0 - x0*y0);
00081   }
00082 
00083   // case 2 ////////////////////////////////////////////////////////////////////
00084 
00085   else {
00086 
00087     CouNumber diff = info -> solution_ [brind] - *brpt;
00088     bool side = (diff > 0.);
00089 
00090     dist [side ? 0 : 1] = CoinMax (fabs (w0 - x0 * y0), fabs (diff));
00091     dist [side ? 1 : 0] = fabs (w0 - x0 *y0);
00092   }
00093 
00094   //dist [0] = dist [1] = 1;
00095   return dist;
00096 }
00097 
00098 }

Generated on Wed Nov 30 03:03:58 2011 by  doxygen 1.4.7