00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "CoinHelperFunctions.hpp"
00013 #include "CouenneProblem.hpp"
00014 #include "CouenneVTObject.hpp"
00015
00016
00019 double CouenneVTObject::infeasibility (const OsiBranchingInformation *info, int &way) const {
00020
00021 int indexVar = reference_ -> Index ();
00022 assert (indexVar >= 0);
00023
00024 CouNumber tol = CoinMin (COUENNE_EPS, feas_tolerance_);
00025
00026
00027 if (info -> upper_ [indexVar] -
00028 info -> lower_ [indexVar] < tol) {
00029 if (reference_ -> isInteger ()) {
00030 double point = info -> solution_ [reference_ -> Index ()];
00031 if (downEstimate_ < point - floor (point)) downEstimate_ = point - floor (point);
00032 if (upEstimate_ < ceil (point) - point) upEstimate_ = ceil (point) - point;
00033 return intInfeasibility (point);
00034 } else return (upEstimate_ = downEstimate_ = 0.);
00035 }
00036
00037
00038 problem_ -> domain () -> push
00039 (problem_ -> nVars (),
00040 info -> solution_,
00041 info -> lower_,
00042 info -> upper_);
00043
00044
00045
00046 if (jnlst_ -> ProduceOutput (J_DETAILED, J_BRANCHING)) {
00047 printf ("VT infeas on ");
00048 reference_ -> print ();
00049 if (reference_ -> Image ()) {
00050 printf (" := ");
00051 reference_ -> Image () -> print ();
00052 }
00053 const std::set <int> &dependence = problem_ -> Dependence () [indexVar];
00054 if (dependence.size () > 0) {
00055 printf (" -- ");
00056 for (std::set <int>::const_iterator i = dependence.begin ();
00057 i != dependence.end (); ++i) {
00058 problem_ -> Var (*i) -> print ();
00059 printf (" ");
00060 }
00061 }
00062 printf ("\n");
00063 }
00064
00065
00066 const std::set <int> &dependence = problem_ -> Dependence () [indexVar];
00067
00068 CouNumber
00069 xcurr = info -> solution_ [indexVar],
00070 retval = 0.,
00071 lFeas = xcurr,
00072 rFeas = xcurr,
00073 leanLeft = 0.,
00074 fx = xcurr,
00075 maxInf = 0.;
00076
00077 if (reference_ -> Type () == AUX)
00078 fx = (*(reference_ -> Image ())) ();
00079
00080 if (dependence.size () == 0) {
00081
00082
00083
00084
00085
00086
00087
00088
00089 retval = (reference_ -> Type () == AUX) ?
00090
00091 (upEstimate_ = downEstimate_ = maxInf = checkInfeasibility (info)) :
00092 0.;
00093
00094
00095 retval = upEstimate_ = downEstimate_ = maxInf = checkInfeasibility (info);
00096
00097 } else {
00098
00099
00100
00101
00102 for (std::set <int>::const_iterator i = dependence.begin ();
00103 i != dependence.end (); ++i) {
00104
00105 const CouenneObject *obj = problem_ -> Objects () [*i];
00106 assert (obj -> Reference ());
00107
00108 CouNumber
00109 left = xcurr,
00110 right = xcurr,
00111 infeas = obj -> checkInfeasibility (info);
00112
00113 if (infeas > maxInf)
00114 maxInf = infeas;
00115
00116
00117 if (infeas > 0.) {
00118
00119
00120
00121
00122
00123 obj -> Reference () -> Image () -> closestFeasible
00124 (reference_, obj -> Reference (), left, right);
00125
00126 if (left < lFeas) lFeas = left;
00127 if (right > rFeas) rFeas = right;
00128 }
00129
00130 if (jnlst_ -> ProduceOutput (J_MATRIX, J_BRANCHING)) {
00131 expression *ref = obj -> Reference ();
00132 jnlst_ -> Printf (J_MATRIX, J_BRANCHING, "[%g,%g] --> %g - %g = %g (diff = %g - %g = %g): ",
00133 left, right, rFeas, lFeas, rFeas - lFeas,
00134 (ref -> Image ()) ?
00135 (*(ref-> Image ())) () : 0.,
00136 (*(ref)) (),
00137 (ref -> Image ()) ?
00138 (*(ref -> Image ())) () - (*(ref)) () : 0.);
00139 ref -> print ();
00140 if (ref -> Image ())
00141 {printf (" := "); ref -> Image() -> print();}
00142 printf ("\n");
00143 }
00144 }
00145
00146 if (lFeas < info -> lower_ [indexVar]) lFeas = info -> lower_ [indexVar];
00147 if (rFeas > info -> upper_ [indexVar]) rFeas = info -> upper_ [indexVar];
00148
00149 retval = rFeas - lFeas;
00150
00151 upEstimate_ = rFeas - xcurr;
00152 downEstimate_ = xcurr - lFeas;
00153
00154
00155
00156
00157 if (upEstimate_ <= tol) upEstimate_ = maxInf;
00158 if (downEstimate_ <= tol) downEstimate_ = maxInf;
00159 }
00160
00162
00163
00164
00165
00166 const CouNumber threshold = .5;
00167
00168 if (retval > COUENNE_EPS) {
00169
00170 leanLeft = (xcurr - lFeas) / retval;
00171
00172 if (leanLeft < threshold) way = 0;
00173 else if (leanLeft > 1 - threshold) way = 1;
00174 else way = (CoinDrand48 () < 0.5) ? 0 : 1;
00175 }
00176
00177
00178
00179
00180
00181 CouNumber vt_delta =
00182 (indexVar == problem_ -> Obj (0) -> Body () -> Index ()) ? 1. : 0.;
00183
00184 for (int i=0, n_el = info -> columnLength_ [indexVar]; i < n_el; i++) {
00185
00186 int indRow = info -> columnStart_ [indexVar] + i;
00187
00188 vt_delta +=
00189 fabs (info -> pi_ [info -> row_ [indRow]] *
00190 info -> elementByColumn_ [indRow]);
00191
00192
00193
00194
00195
00196 jnlst_ -> Printf (J_MATRIX, J_BRANCHING, "+ (pi[%d]=%g) * (el[%d]=%g) [=%g] --> vtd = %g\n",
00197 info -> row_ [indRow],
00198 info -> pi_ [info -> row_ [indRow]],
00199 indRow,
00200 info -> elementByColumn_ [indRow],
00201 info -> pi_ [info -> row_ [indRow]] *
00202 info -> elementByColumn_ [indRow],
00203 vt_delta);
00204 }
00205
00206
00207 const CouNumber
00208 alpha = 1.0,
00209 beta = 0.0;
00210
00211 jnlst_ -> Printf (J_MATRIX, J_BRANCHING, "return %g * %g + %g * %g + %g * %g --> ",
00212 alpha, fabs (retval * vt_delta), beta, retval,
00213 1-alpha-beta, leanLeft * (1-leanLeft));
00214
00215 retval =
00216 alpha * fabs (retval*vt_delta) +
00217 beta * retval +
00218 (1-alpha-beta) * leanLeft * (1-leanLeft);
00219
00220 if (jnlst_ -> ProduceOutput (J_MATRIX, J_BRANCHING)) {
00221 if (retval > CoinMin (COUENNE_EPS, feas_tolerance_)) {
00222 printf ("vt-delta is %-10g [", retval);
00223 reference_ -> print ();
00224 if (reference_ -> Image ()) {
00225 printf (" := ");
00226 reference_ -> Image () -> print ();
00227 }
00228 if (dependence.size () > 0) {
00229 printf (" -- ");
00230 for (std::set <int>::const_iterator i = dependence.begin ();
00231 i != dependence.end (); ++i) {
00232 problem_ -> Var (*i) -> print ();
00233 printf (" ");
00234 }
00235 }
00236 printf ("]\n");
00237 } else printf ("feasible...\n");
00238 }
00239
00240 problem_ -> domain () -> pop ();
00241
00242 if ((retval < tol) &&
00243 (maxInf > tol)) {
00244
00245
00246
00247
00248 retval = maxInf;
00249 }
00250
00251 if (retval < CoinMin (COUENNE_EPS, feas_tolerance_))
00252 retval = 0.;
00253
00254 #define ALMOST_ZERO 1e-8
00255
00256 assert ((retval < ALMOST_ZERO && upEstimate_ < ALMOST_ZERO && downEstimate_ < ALMOST_ZERO) ||
00257 (retval > ALMOST_ZERO && upEstimate_ > ALMOST_ZERO && downEstimate_ > ALMOST_ZERO));
00258
00259 return (reference_ -> isInteger ()) ?
00260 CoinMax (retval, intInfeasibility (info -> solution_ [reference_ -> Index ()])) :
00261 retval;
00262 }