00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CoinHelperFunctions.hpp"
00012
00013 #include "exprQuad.hpp"
00014 #include "CouenneObject.hpp"
00015 #include "CouenneBranchingObject.hpp"
00016
00017
00018
00021 CouNumber exprQuad::selectBranch (const CouenneObject *obj,
00022 const OsiBranchingInformation *info,
00023 expression *&var,
00024 double * &brpts,
00025 double * &brDist,
00026
00027 int &way) {
00028 int ind = -1;
00029
00030
00031
00032 CouNumber delta = (*(obj -> Reference ())) () - (*this) ();
00033
00034
00035
00036
00037
00038
00039
00040 brpts = (double *) realloc (brpts, sizeof (double));
00041 brDist = (double *) realloc (brDist, 2*sizeof (double));
00042
00043 way = TWO_RAND;
00044
00045
00046
00047
00048
00049 std::vector <std::pair <CouNumber,
00050 std::vector <std::pair <exprVar *, CouNumber> > > >::iterator fi = eigen_.begin ();
00051
00052 std::vector <std::pair <CouNumber,
00053 std::vector <std::pair <exprVar *, CouNumber> > > >::reverse_iterator ri = eigen_.rbegin ();
00054
00055 CouNumber max_span = -COUENNE_INFINITY;
00056
00057 bool changed_sign = false;
00058
00060
00061 for (;((delta < 0.) && (fi != eigen_. end ()) ||
00062 (delta > 0.) && (ri != eigen_. rend ()));
00063 ++fi, ++ri) {
00064
00065 std::vector <std::pair <exprVar *, CouNumber> > &ev =
00066 (delta < 0.) ? fi -> second : ri -> second;
00067
00068 if ((delta < 0.) && (fi -> first > 0.) ||
00069 (delta > 0.) && (ri -> first < 0.)) {
00070
00071 if (max_span > 0.) break;
00072 changed_sign = true;
00073
00074 }
00075
00076 for (std::vector <std::pair <exprVar *, CouNumber> >::iterator j = ev.begin ();
00077 j != ev.end (); ++j) {
00078
00079 int index = j -> first -> Index ();
00080
00081 CouNumber
00082 lb = info -> lower_ [index],
00083 ub = info -> upper_ [index];
00084
00085
00086 if (fabs (ub-lb) > COUENNE_EPS) {
00087
00088
00089
00090
00091
00092
00093 CouNumber span = -1;
00094
00095 if ((lb < -COUENNE_INFINITY) ||
00096 (ub > COUENNE_INFINITY) ||
00097 ((span = (ub-lb) * fabs (j -> second)) > max_span + COUENNE_EPS)) {
00098
00099 ind = index;
00100 var = j -> first;
00101
00102 *brpts = obj -> midInterval (info -> solution_ [index], lb, ub);
00103
00104 if (changed_sign)
00105 break;
00106
00107 if (span >= 0) max_span = span;
00108 else break;
00109 }
00110 }
00111 }
00112 }
00113
00114 if ((eigen_.size () == 0)
00115 || (ind < 0)) {
00116
00117 CouNumber max_span = -COUENNE_INFINITY;
00118
00119 for (std::map <exprVar *, std::pair <CouNumber, CouNumber> >::iterator i = bounds_. begin ();
00120 i != bounds_. end (); ++i) {
00121
00122 CouNumber
00123 lb = i -> second.first,
00124 ub = i -> second.second,
00125 span = ub - lb;
00126
00127 if ((span > COUENNE_EPS) &&
00128 (span > max_span)) {
00129
00130 var = i -> first;
00131 ind = var -> Index ();
00132 }
00133 }
00134
00135 if (ind < 0) {
00136
00137 var = obj -> Reference ();
00138 ind = var -> Index ();
00139
00140 *brpts = obj -> midInterval (info -> solution_ [ind],
00141 info -> lower_ [ind],
00142 info -> upper_ [ind]);
00143 }
00144 else *brpts = obj -> midInterval (info -> solution_ [ind],
00145 info -> lower_ [ind],
00146 info -> upper_ [ind]);
00147
00148 }
00149
00150 return (brDist [0] = brDist [1] = fabs (delta));
00151 }