00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "CouenneTypes.hpp"
00011 #include "CouenneExprTrilinear.hpp"
00012 #include "CouenneExprMin.hpp"
00013 #include "CouenneExprMax.hpp"
00014 #include "CouenneExprClone.hpp"
00015 #include "CouenneProblem.hpp"
00016
00017 using namespace Couenne;
00018
00020 void exprTrilinear::getBounds (expression *&lb, expression *&ub) {
00021
00022 expression
00023 **arglistMax = new expression* [16],
00024 **arglistMin = new expression* [16],
00025 **lbA = new expression* [3],
00026 **ubA = new expression* [3];
00027
00028 for (int i=0; i<3; i++)
00029 arglist_ [i] -> getBounds (lbA [i], ubA [i]);
00030
00031 for (int i0 = 0; i0 < 2; i0++)
00032 for (int i1 = 0; i1 < 2; i1++)
00033 for (int i2 = 0; i2 < 2; i2++) {
00034
00035 int indexTerm = i0*8 + i1*4 + i2*2;
00036
00037 expression *product = new exprTrilinear (new exprClone (i0 ? ubA [0] : lbA [0]),
00038 new exprClone (i1 ? ubA [1] : lbA [1]),
00039 new exprClone (i2 ? ubA [2] : lbA [2]));
00040
00041 arglistMax [indexTerm] = new exprCopy (product);
00042
00043 arglistMin [indexTerm] = new exprCopy (new exprClone (product));
00044
00045 arglistMax [indexTerm + 1] = new exprStore (arglistMax [indexTerm]);
00046 arglistMin [indexTerm + 1] = new exprStore (arglistMin [indexTerm]);
00047 }
00048
00049 lb = new exprMin (arglistMin, 16);
00050 ub = new exprMax (arglistMax, 16);
00051 }
00052
00053
00055
00056 void exprTrilinear::getBounds (CouNumber &lb, CouNumber &ub) {
00057
00058 CouNumber
00059 lbA [3],
00060 ubA [3];
00061
00062 for (int i=0; i<3; i++)
00063 arglist_ [i] -> getBounds (lbA [i], ubA [i]);
00064
00065 lb = COUENNE_INFINITY;
00066 ub = -COUENNE_INFINITY;
00067
00068 for (int i0 = 0; i0 < 2; i0++)
00069 for (int i1 = 0; i1 < 2; i1++)
00070 for (int i2 = 0; i2 < 2; i2++) {
00071
00072 register double curbound =
00073 (i0 ? ubA [0] : lbA [0]) *
00074 (i1 ? ubA [1] : lbA [1]) *
00075 (i2 ? ubA [2] : lbA [2]);
00076
00077 if (curbound < lb) lb = curbound;
00078 if (curbound > ub) ub = curbound;
00079 }
00080
00081 bool isInt = true;
00082
00083 for (int i=0; i<3; i++)
00084 if (!(arglist_ [i] -> isInteger ())) {
00085 isInt = false;
00086 break;
00087 }
00088
00089 if (isInt) {
00090 lb = ceil (lb - COUENNE_EPS);
00091 ub = floor (ub + COUENNE_EPS);
00092 }
00093 }