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

Go to the documentation of this file.
00001 /* $Id: branchExprTrilinear.cpp 490 2011-01-14 16:07:12Z pbelotti $
00002  *
00003  * Name:    branchExprTrilinear.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: return branch data for trilinear terms
00006  *
00007  * This file is licensed under the Eclipse Public License (EPL)
00008  */
00009 
00010 #include "CouennePrecisions.hpp"
00011 #include "CouenneTypes.hpp"
00012 #include "CouenneObject.hpp"
00013 
00014 #include "CouenneExprTrilinear.hpp"
00015 #include "CouenneFunTriplets.hpp"
00016 #include "CouenneProjections.hpp"
00017 
00018 using namespace Couenne;
00019 
00022 CouNumber exprTrilinear::selectBranch (const CouenneObject *obj,
00023                                        const OsiBranchingInformation *info,
00024                                        expression *&var,
00025                                        double * &brpts, 
00026                                        double * &brDist, // distance of current LP point 
00027                                                          // to new convexifications
00028                                        int &way) {
00029 
00030   if (brDist) {free (brDist); brDist = NULL;} // clear it, computeMulBrDist will fill it
00031 
00032   int
00033     xi = arglist_ [0] -> Index (),
00034     yi = arglist_ [1] -> Index (),
00035     zi = arglist_ [2] -> Index ();
00036 
00037   assert ((xi >= 0) && (yi >= 0) && (zi >= 0));
00038 
00039   CouNumber 
00040     xl = info -> lower_     [xi], yl = info -> lower_     [yi], zl = info -> lower_     [zi],
00041     xu = info -> upper_     [xi], yu = info -> upper_     [yi], zu = info -> upper_     [zi];
00042 
00043   brpts  = (double *) realloc (brpts,      sizeof (double));
00044   brDist = (double *) realloc (brDist, 2 * sizeof (double));
00045 
00046   // case 0: term is fixed
00047 
00048   if ((fabs (xu - xl) < COUENNE_EPS) &&
00049       (fabs (xu - xl) < COUENNE_EPS) &&
00050       (fabs (xu - xl) < COUENNE_EPS)) {
00051 
00052     var = NULL;
00053     return 0.;
00054   }
00055 
00056   // a very simple branching scheme: 
00057   //
00058   //            if any bound interval is (-inf,+inf), break it by branching at zero
00059   // otherwise, if any bound interval is [a,+inf) or (-inf,b], 
00060   //              break it by branching at zero (if interval includes zero) or 
00061   //                                    at 2a-1 (resp. 2b+1)
00062   // otherwise, branch on the largest bound, in the middle 
00063   
00064   if ((xl < -COUENNE_INFINITY) && (xu > COUENNE_INFINITY)) {*brpts = 0.; brDist [0] = brDist [1] = 1.; var = arglist_ [0]; return 1.;}
00065   if ((yl < -COUENNE_INFINITY) && (yu > COUENNE_INFINITY)) {*brpts = 0.; brDist [0] = brDist [1] = 1.; var = arglist_ [1]; return 1.;}
00066   if ((zl < -COUENNE_INFINITY) && (zu > COUENNE_INFINITY)) {*brpts = 0.; brDist [0] = brDist [1] = 1.; var = arglist_ [2]; return 1.;}
00067 
00068 
00069 #define SETBNDS(l,u,ind) {                      \
00070 \
00071   if (l < -COUENNE_INFINITY) {\
00072     if (u > 1.) {*brpts = 0.;               brDist [0] = brDist [1] = 1.; var = arglist_ [ind]; return 1.;}\
00073     else        {*brpts = 2*-fabs (u) - 1.; brDist [0] = brDist [1] = 1.; var = arglist_ [ind]; return 1.;}\
00074   }\
00075 \
00076   if (u >  COUENNE_INFINITY) {\
00077     if (l < -1.) {*brpts = 0.;              brDist [0] = brDist [1] = 1.; var = arglist_ [ind]; return 1.;}\
00078     else         {*brpts = 2*fabs (u) + 1.; brDist [0] = brDist [1] = 1.; var = arglist_ [ind]; return 1.;}\
00079   }\
00080 }
00081 
00082   SETBNDS (xl, xu, 0);
00083   SETBNDS (xl, xu, 1);
00084   SETBNDS (xl, xu, 2);
00085 
00086   // bounds all finite, choose largest bound interval width
00087   if      ((xu - xl > yu - yl) && (xu - xl > zu - zl)) {*brpts = .5 * (xl + xu); brDist [0] = brDist [1] = 1.; var = arglist_ [0]; return 1.;}
00088   else if ((yu - yl > zu - zl))                        {*brpts = .5 * (yl + yu); brDist [0] = brDist [1] = 1.; var = arglist_ [1]; return 1.;}
00089   else                                                 {*brpts = .5 * (zl + zu); brDist [0] = brDist [1] = 1.; var = arglist_ [2]; return 1.;}
00090 }

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