00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CoinHelperFunctions.hpp"
00012
00013 #include "CouenneExprExp.hpp"
00014 #include "CouenneObject.hpp"
00015 #include "CouenneBranchingObject.hpp"
00016 #include "CouenneProjections.hpp"
00017 #include "CouenneFunTriplets.hpp"
00018
00019 using namespace Couenne;
00020
00023 CouNumber exprExp::selectBranch (const CouenneObject *obj,
00024 const OsiBranchingInformation *info,
00025 expression *&var,
00026 double * &brpts,
00027 double * &brDist,
00028
00029 int &way) {
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 var = argument_;
00047
00048 brDist = (double *) realloc (brDist, 2 * sizeof (double));
00049 brpts = (double *) realloc (brpts, sizeof (double));
00050
00051 int
00052 ind = var -> Index (),
00053 wi = obj -> Reference () -> Index ();
00054
00055 assert ((ind >= 0) && (wi >= 0));
00056
00057 CouNumber y0 = info -> solution_ [wi],
00058 x0 = info -> solution_ [ind],
00059 l = info -> lower_ [ind],
00060 u = info -> upper_ [ind];
00061
00062
00063
00064 if (y0 < exp (x0)) {
00065
00066
00067
00068
00069 *brpts = obj -> midInterval (powNewton (x0, y0, exp, exp, exp), l, u, info);
00070
00071 way = TWO_RAND;
00072
00073 y0 -= exp (*brpts);
00074 x0 -= *brpts;
00075
00076 return sqrt (brDist [0] = brDist [1] = sqrt (x0*x0 + y0*y0));
00077 }
00078
00079
00080
00081 if ((l < -COUENNE_INFINITY) &&
00082 (u > COUENNE_INFINITY)) {
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 *brpts = 0.5 * (x0 + log (y0));
00100 way = TWO_RAND;
00101
00102 return CoinMin (brDist [0] = log (y0) - x0,
00103 brDist [1] = y0 - exp (x0));
00104 }
00105
00106
00107
00108 if (l < - COUENNE_INFINITY) {
00109
00110 *brpts = obj -> midInterval (x0, l, u, info);
00111
00112 way = TWO_RIGHT;
00113 return CoinMin (brDist [0] = y0 - exp (x0),
00114 brDist [1] = projectSeg (x0, y0, *brpts, exp (*brpts), u, exp (u), -1));
00115 }
00116
00117 if (u > COUENNE_INFINITY) {
00118
00119 *brpts = obj -> midInterval (log (y0), l, u, info);
00120
00121 way = TWO_LEFT;
00122 return CoinMin (brDist [0] = projectSeg (x0, y0, l, exp (l), *brpts, exp (*brpts), -1),
00123 brDist [1] = log (y0) - x0);
00124
00125 }
00126
00127
00128
00129 simpletriplet ft (exp, exp, exp, log);
00130 *brpts = obj -> getBrPoint (&ft, x0, l, u, info);
00131
00132 way = TWO_RAND;
00133
00134
00135 return CoinMin (brDist [0] = projectSeg (x0, y0, l, exp (l), *brpts, exp (*brpts), -1),
00136 brDist [1] = projectSeg (x0, y0, *brpts, exp (*brpts), u, exp (u), -1));
00137 }