00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CouenneTypes.hpp"
00012 #include "CouennePrecisions.hpp"
00013 #include "CouenneProblem.hpp"
00014 #include "math.h"
00015 #include "CouenneBTPerfIndicator.hpp"
00016
00017 using namespace Couenne;
00018
00020 void CouenneBTPerfIndicator::update (const CouNumber *lb, const CouNumber *ub, int depth) const {
00021
00022 assert (oldLB_ != NULL &&
00023 oldUB_ != NULL);
00024
00025 double
00026 curWei = 1. / CoinMax (1., (double) depth),
00027 newWS = weightSum_ + curWei;
00028
00029
00030
00031 int
00032 nFixed = 0,
00033 nShr = 0,
00034 nShrDbl = 0,
00035 nPrInf = 0;
00036
00037 double ratio = 0.;
00038
00039 CouNumber *optimum = problem_ -> bestSol ();
00040
00041 for (int i=0; i<problem_ -> nVars (); ++i) {
00042
00043 CouNumber
00044 olb = oldLB_ [i], oub = oldUB_ [i],
00045 nlb = lb [i], nub = ub [i];
00046
00047 if (nlb < olb) nlb = olb;
00048 if (nub > oub) nub = oub;
00049
00050
00051
00052 if (optimum &&
00053 ((optimum [i] < nlb - COUENNE_EPS && optimum [i] >= olb) ||
00054 (optimum [i] > nub + COUENNE_EPS && optimum [i] <= oub)))
00055
00056 printf (" %30s cuts optimum at x_%d=%e: [%e,%e] --> [%e,%e], diff:%e\n",
00057 name_.c_str (),
00058 i, optimum [i],
00059 olb, oub,
00060 nlb, nub,
00061 CoinMax (nlb - optimum [i],
00062 optimum [i] - nub));
00063
00064
00065
00066 if ((((olb > -COUENNE_INFINITY / 1e4) && (nlb < olb - COUENNE_EPS)) ||
00067 ((oub < COUENNE_INFINITY / 1e4) && (nub > oub + COUENNE_EPS))) &&
00068 ((nlb >= nub + 2 - 1e-5) && i == 0))
00069
00070 printf (" %30s makes bound worse (x%d): [%e,%e] --> [%e,%e], diff:%e\n",
00071 name_.c_str (),
00072 i,
00073 olb, oub,
00074 nlb, nub,
00075 CoinMax (olb - nlb,
00076 nub - oub));
00077
00078 if (fabs (nlb - nub) < COUENNE_EPS) {
00079
00080 if (fabs (olb - oub) > COUENNE_EPS)
00081 ++nFixed;
00082
00083 } else if (nlb >= nub + 1e2 * COUENNE_EPS) {
00084
00085 ++ nPrInf;
00086 nFixed = nShr = nShrDbl = 0;
00087 ratio = 0.;
00088 break;
00089
00090 } else if ((nlb > -COUENNE_INFINITY) &&
00091 (nub < COUENNE_INFINITY)) {
00092
00093 if (olb <= -COUENNE_INFINITY ||
00094 oub >= COUENNE_INFINITY) {
00095
00096 if ((olb <= -COUENNE_INFINITY) &&
00097 (oub >= COUENNE_INFINITY))
00098
00099 nShr += 2;
00100
00101 else ++nShr;
00102
00103 } else {
00104
00105
00106
00107 ratio += (log (CoinMax (1e-6, oub - olb)) -
00108 log (CoinMax (1e-6, nub - nlb)));
00109
00110
00111
00112
00113
00114
00115
00116
00117 }
00118 } else if ((olb <= -COUENNE_INFINITY) &&
00119 (oub >= COUENNE_INFINITY))
00120 ++nShrDbl;
00121 }
00122
00123
00124
00125 ++nRuns_;
00126
00127 ratio /= log ((double) 2.);
00128
00129 boundRatio_ = (boundRatio_ * weightSum_ + curWei * ratio) / newWS;
00130 shrunkInf_ = (shrunkInf_ * weightSum_ + curWei * nShr) / newWS;
00131 shrunkDoubleInf_ = (shrunkDoubleInf_ * weightSum_ + curWei * nShrDbl) / newWS;
00132 nFixed_ = (nFixed_ * weightSum_ + curWei * nFixed) / newWS;
00133
00134 nProvedInfeas_ += nPrInf;
00135
00136 weightSum_ = newWS;
00137
00138 delete [] oldLB_;
00139 delete [] oldUB_;
00140
00141 oldLB_ = NULL;
00142 oldUB_ = NULL;
00143 }