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