00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "exprDiv.hpp"
00012 #include "exprMul.hpp"
00013 #include "CouenneBranchingObject.hpp"
00014 #include "CouenneObject.hpp"
00015
00016
00019 CouNumber exprDiv::selectBranch (const CouenneObject *obj,
00020 const OsiBranchingInformation *info,
00021 expression *&var,
00022 double * &brpts,
00023 double * &brDist,
00024
00025 int &way) {
00026
00027 if (brDist) {free (brDist); brDist = NULL;}
00028
00029 int xi = arglist_ [0] -> Index (),
00030 yi = arglist_ [1] -> Index (),
00031 wi = obj -> Reference () -> Index ();
00032
00033 assert ((xi >= 0) && (yi >= 0) && (wi >= 0));
00034
00035
00036
00037
00038 CouNumber yl = info -> lower_ [yi],
00039 yu = info -> upper_ [yi],
00040 y0 = info -> solution_ [yi];
00041
00042
00043
00044 if ((yl < -COUENNE_EPS) &&
00045 (yu > COUENNE_EPS)) {
00046
00047 var = arglist_ [1];
00048 brpts = (double *) realloc (brpts, sizeof (double));
00049
00050 *brpts = 0.;
00051
00052 way = (y0 > *brpts) ? TWO_RIGHT : TWO_LEFT;
00053
00054 brDist = computeMulBrDist (info, wi, yi, xi, yi, brpts);
00055
00056 return CoinMin (brDist [0], brDist [1]);
00057
00058
00059
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 if ((yl < -COUENNE_INFINITY) ||
00074 (yu > COUENNE_INFINITY)) {
00075
00076 var = arglist_ [1];
00077 brpts = (double *) realloc (brpts, sizeof (CouNumber));
00078
00079
00080 if (fabs (y0-yl) < COUENNE_NEAR_BOUND) *brpts = y0 + 1. + yl*10.;
00081 else if (fabs (y0-yu) < COUENNE_NEAR_BOUND) *brpts = y0 - 1. + yu*10.;
00082 else *brpts = y0;
00083
00084 way = (y0 > 0.) ? TWO_LEFT : TWO_RIGHT;
00085
00086 brDist = computeMulBrDist (info, wi, yi, xi, yi, brpts);
00087
00088 return CoinMin (brDist [0], brDist [1]);
00089
00090
00091
00092 }
00093
00094
00095
00096
00097 CouNumber wl = info -> lower_ [wi],
00098 wu = info -> upper_ [wi],
00099 w0 = info -> solution_ [wi],
00100 x0 = info -> solution_ [xi];
00101
00102
00103
00104 if ((wl < -COUENNE_INFINITY) ||
00105 (wu > COUENNE_INFINITY)) {
00106
00107 var = obj -> Reference ();
00108
00109 if ((wl < -COUENNE_INFINITY) &&
00110 (wu > COUENNE_INFINITY)) {
00111
00112 CouNumber
00113 wreal = x0 / y0,
00114 wmin = w0,
00115 wmax = wreal;
00116
00117 if (wreal < w0) {
00118 wmin = wreal;
00119 wmax = w0;
00120 }
00121
00122 brpts = (double *) realloc (brpts, sizeof (CouNumber));
00123 *brpts = wreal;
00124 way = (w0 < wreal) ? TWO_LEFT : TWO_RIGHT;
00125
00126 brDist = computeMulBrDist (info, wi, yi, xi, wi, brpts);
00127 return CoinMin (brDist [0], brDist [1]);
00128
00129 } else {
00130
00131
00132
00133 brpts = (double *) realloc (brpts, sizeof (CouNumber));
00134
00135
00136 if (fabs (w0-wl) < COUENNE_NEAR_BOUND) *brpts = w0 + 1 + wl*10;
00137 else if (fabs (w0-wu) < COUENNE_NEAR_BOUND) *brpts = w0 - 1 + wu*10;
00138 else *brpts = w0;
00139
00140 way = (wl < - COUENNE_INFINITY) ? TWO_RIGHT : TWO_LEFT;
00141
00142 brDist = computeMulBrDist (info, wi, yi, xi, wi, brpts);
00143 return CoinMin (brDist [0], brDist [1]);
00144 }
00145
00146 }
00147
00148
00149
00150 CouNumber
00151 xl = info -> lower_ [xi],
00152 xu = info -> upper_ [xi],
00153 dx = xu-xl,
00154 dy = yu-yl,
00155 dw = wu-wl;
00156
00157 brpts = (double *) realloc (brpts, sizeof (CouNumber));
00158
00159
00160
00161
00162
00163 way = TWO_RAND;
00164
00165 if (dx > dy)
00166 if (dx > dw) {var = arglist_[0]; *brpts = (xl+xu)/2.; }
00167 else {var = obj->Reference(); *brpts = (wl+wu)/2.; }
00168 else
00169 if (dy > dw) {var = arglist_[1]; *brpts = (yl+yu)/2.; }
00170 else {var = obj->Reference(); *brpts = (wl+wu)/2.; }
00171
00172 brDist = computeMulBrDist (info, wi, yi, xi, var -> Index (), brpts);
00173 return CoinMin (brDist [0], brDist [1]);
00174 }