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