00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <queue>
00012
00013 #include "CouenneTypes.hpp"
00014 #include "CouenneExprMul.hpp"
00015 #include "CouenneExprTrilinear.hpp"
00016 #include "CouenneExprBMul.hpp"
00017 #include "CouenneExprConst.hpp"
00018 #include "CouenneExprPow.hpp"
00019 #include "CouenneExprAux.hpp"
00020 #include "CouenneExprClone.hpp"
00021 #include "CouenneProblem.hpp"
00022
00023 using namespace Couenne;
00024
00025
00027
00028 void exprMul::getBounds (expression *&lb, expression *&ub) {
00029
00030 int i;
00031
00032 if ((arglist_ [i=0] -> Type () == CONST) ||
00033 (arglist_ [i=1] -> Type () == CONST)) {
00034
00035 CouNumber c = arglist_ [i] -> Value ();
00036
00037 if (!i && (arglist_ [1] -> Type () == CONST)) {
00038
00039
00040
00041
00042 CouNumber prod = c * arglist_ [1] -> Value ();
00043
00044 lb = new exprConst (prod);
00045 ub = new exprConst (prod);
00046
00047 return;
00048 }
00049 else {
00050
00051
00052
00053 expression *lbi, *ubi;
00054 arglist_ [1-i] -> getBounds (lbi, ubi);
00055
00056 if (c >= 0) {
00057 lb = new exprMul (new exprConst (c), lbi);
00058 ub = new exprMul (new exprConst (c), ubi);
00059 } else {
00060 lb = new exprMul (new exprConst (c), ubi);
00061 ub = new exprMul (new exprConst (c), lbi);
00062 }
00063 }
00064 }
00065 else {
00066
00067
00068
00069 expression **almin = new expression * [4];
00070 expression **almax = new expression * [4];
00071
00072 arglist_ [0] -> getBounds (almin [0], almin [1]);
00073 arglist_ [1] -> getBounds (almin [2], almin [3]);
00074
00075 almax [0] = new exprClone (almin [0]);
00076 almax [1] = new exprClone (almin [1]);
00077 almax [2] = new exprClone (almin [2]);
00078 almax [3] = new exprClone (almin [3]);
00079
00080 lb = new exprLBMul (almin, 4);
00081 ub = new exprUBMul (almax, 4);
00082 }
00083 }
00084
00085
00087
00088 void exprMul::getBounds (CouNumber &lb, CouNumber &ub) {
00089
00090 CouNumber lb1, ub1, lb2, ub2;
00091
00092 arglist_ [0] -> getBounds (lb1, ub1);
00093 arglist_ [1] -> getBounds (lb2, ub2);
00094
00095 if (ub1 < 0) {
00096 if (ub2 < 0) {lb = safeProd(ub1,ub2); ub = safeProd(lb1,lb2);}
00097 else if (lb2 > 0) {lb = safeProd(lb1,ub2); ub = safeProd(ub1,lb2);}
00098 else {lb = safeProd(lb1,ub2); ub = safeProd(lb1,lb2);}
00099 } else if (lb1 > 0) {
00100 if (ub2 < 0) {lb = safeProd(ub1,lb2); ub = safeProd(lb1,ub2);}
00101 else if (lb2 > 0) {lb = safeProd(lb1,lb2); ub = safeProd(ub1,ub2);}
00102 else {lb = safeProd(ub1,lb2); ub = safeProd(ub1,ub2);}
00103 } else {
00104 if (ub2 < 0) {lb = safeProd(ub1,lb2); ub = safeProd(lb1,lb2);}
00105 else if (lb2 > 0) {lb = safeProd(lb1,ub2); ub = safeProd(ub1,ub2);}
00106 else {lb = CoinMin (safeProd(lb1,ub2), safeProd(lb2,ub1));
00107 ub = CoinMax (safeProd(lb1,lb2), safeProd(ub1,ub2));}
00108 }
00109 }