00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "BonTNLPSolver.hpp"
00014 #include "BonNlpHeuristic.hpp"
00015 #include "CoinHelperFunctions.hpp"
00016 #include "BonCouenneInfo.hpp"
00017
00018 #include "CouenneCutGenerator.hpp"
00019 #include "CouenneProblem.hpp"
00020
00021 #define MAX_ABT_ITER 1 // max # aggressive BT iterations
00022 #define THRES_ABT_IMPROVED 0 // only continue ABT if at least these bounds have improved
00023 #define THRES_ABT_ORIG 1000 // only do ABT on originals if they are more than this
00024
00025 static double distanceToBound(int n, const double* xOrig,
00026 const double* lower, const double* upper)
00027 {
00028 double Xdist = 0.;
00029 for (int i=0; i<n; i++) {
00030 if (lower[i] > xOrig[i]) {
00031 Xdist += lower[i] - xOrig[i];
00032 }
00033 if (upper[i] < xOrig[i]) {
00034 Xdist += xOrig[i] - upper[i];
00035 }
00036 }
00037 return Xdist;
00038 }
00039
00040
00041
00042
00043
00044
00045 bool CouenneProblem::aggressiveBT (Bonmin::OsiTMINLPInterface *nlp,
00046 t_chg_bounds *chg_bds,
00047 Bonmin::BabInfo * babInfo) const {
00048
00049 Jnlst()->Printf (J_ITERSUMMARY, J_BOUNDTIGHTENING, "Aggressive FBBT\n");
00050
00051 Bonmin::CouenneInfo* couInfo =
00052 dynamic_cast<Bonmin::CouenneInfo*>(babInfo);
00053
00054 int ncols = nVars ();
00055 bool retval = true;
00056
00057 CouNumber
00058 *olb = new CouNumber [ncols],
00059 *oub = new CouNumber [ncols];
00060
00061
00062 CoinCopyN (Lb (), ncols, olb);
00063 CoinCopyN (Ub (), ncols, oub);
00064
00065
00066
00067 SmartPtr<const Bonmin::CouenneInfo::NlpSolution> closestSol;
00068 double dist = 1e50;
00069
00070 const std::list<SmartPtr<const Bonmin::CouenneInfo::NlpSolution> >& solList =
00071 couInfo->NlpSolutions();
00072
00073 for (std::list<SmartPtr<const Bonmin::CouenneInfo::NlpSolution> >::const_iterator
00074 i = solList.begin();
00075 i != solList.end(); i++) {
00076 assert(nOrigVars_ == (*i)->nVars());
00077 const double thisDist = distanceToBound(nOrigVars_, (*i)->solution(), olb, oub);
00078 if (thisDist < dist) {
00079 closestSol = *i;
00080 dist = thisDist;
00081 }
00082 }
00083
00084 jnlst_ -> Printf(J_VECTOR, J_BOUNDTIGHTENING, "best dist = %e\n", dist);
00085
00086
00087 if (dist > 0.1) {
00088
00089
00090
00091 int nvars = nVars ();
00092
00093 double *lower = new double [nvars];
00094 double *upper = new double [nvars];
00095
00096 CoinFillN (lower, nvars, -COUENNE_INFINITY);
00097 CoinFillN (upper, nvars, COUENNE_INFINITY);
00098
00099 CoinCopyN (nlp -> getColLower (), nOrigVars_, lower);
00100 CoinCopyN (nlp -> getColUpper (), nOrigVars_, upper);
00101
00102 double *Y = new double [nvars];
00103 CoinFillN (Y, nvars, 0.);
00104 CoinCopyN (X (), nOrigVars_, Y);
00105
00106 if (getIntegerCandidate (nlp -> getColSolution (), Y, lower, upper) < 0) {
00107 jnlst_ -> Printf(J_ITERSUMMARY, J_BOUNDTIGHTENING, "TODO: find NLP point in ABT failed\n");
00108 delete [] Y;
00109 delete [] lower;
00110 delete [] upper;
00111 return true;
00112 }
00113
00115
00116 nlp -> setColLower (lower);
00117 nlp -> setColUpper (upper);
00118 nlp -> setColSolution (Y);
00119
00120 try {
00121 nlp -> initialSolve ();
00122 }
00123 catch (Bonmin::TNLPSolver::UnsolvedError *E) {
00124 }
00125
00126 delete [] Y;
00127 delete [] lower;
00128 delete [] upper;
00129
00130 if (nlp->isProvenOptimal()) {
00131 closestSol = new Bonmin::CouenneInfo::NlpSolution
00132 (nOrigVars_, nlp->getColSolution(), nlp->getObjValue());
00133 couInfo->addSolution(closestSol);
00134 dist = 0.;
00135 }
00136 else {
00137 jnlst_ -> Printf(J_ITERSUMMARY, J_BOUNDTIGHTENING, "TODO: NLP solve in ABT failed\n");
00138 return true;
00139 }
00140 }
00141
00142 if (dist>1e10) {
00143 jnlst_ -> Printf(J_ITERSUMMARY, J_BOUNDTIGHTENING, "TODO: Don't have point for ABT\n");
00144 return true;
00145 }
00146
00147
00148
00149
00150
00151 double *X = new double [ncols];
00152 CoinCopyN (closestSol->solution(), nOrigVars_, X);
00153 getAuxs (X);
00154
00155
00156 t_chg_bounds *f_chg = new t_chg_bounds [ncols];
00157
00158 if (Jnlst()->ProduceOutput(J_ITERSUMMARY, J_BOUNDTIGHTENING)) {
00159
00160 int objind = Obj (0) -> Body () -> Index ();
00161 for (int i=0; i<nOrigVars_; i++)
00162 Jnlst()->Printf(J_MOREVECTOR, J_BOUNDTIGHTENING,
00163 " %2d %+20g [%+20g %+20g]\n",
00164 i, X [i], Lb (i), Ub (i));
00165 Jnlst()->Printf(J_ITERSUMMARY, J_BOUNDTIGHTENING,
00166 "-------------\nAggressive BT. Current bound = %g, cutoff = %g, %d vars\n",
00167 Lb (objind), getCutOff (), ncols);
00168 }
00169
00170 int improved, second, iter = 0;
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 do {
00181
00182 improved = 0;
00183
00184
00185 for (int i=0; i<ncols; i++) {
00186
00187 if (CoinCpuTime () > maxCpuTime_)
00188 break;
00189
00190 int index = evalOrder (i);
00191
00192 if (Var (index) -> Multiplicity () <= 0)
00193 continue;
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 if ((nOrigVars_ < THRES_ABT_ORIG) || (index < nOrigVars_)) {
00206
00207
00208
00209 Jnlst()->Printf(J_DETAILED, J_BOUNDTIGHTENING,
00210 "------------- tighten left x%d\n", index);
00211
00212
00213 if ((X [index] >= Lb (index) + COUENNE_EPS)
00214 && ((improved = fake_tighten (0, index, X, olb, oub, chg_bds, f_chg)) < 0)) {
00215 retval = false;
00216 break;
00217 }
00218
00219 second = 0;
00220
00221 Jnlst()->Printf(J_DETAILED, J_BOUNDTIGHTENING,
00222 "------------- tighten right x%d\n", index);
00223
00224
00225 if ((X [index] <= Ub (index) - COUENNE_EPS)
00226 && ((second = fake_tighten (1, index, X, olb, oub, chg_bds, f_chg) < 0))) {
00227 retval = false;
00228 break;
00229 }
00230
00231 improved += second;
00232 }
00233 }
00234 } while (retval && (improved > THRES_ABT_IMPROVED) && (iter++ < MAX_ABT_ITER));
00235
00236
00237 CoinCopyN (olb, ncols, Lb ());
00238 CoinCopyN (oub, ncols, Ub ());
00239
00240 if (Jnlst()->ProduceOutput(J_ITERSUMMARY, J_BOUNDTIGHTENING)) {
00241 Jnlst()->Printf(J_ITERSUMMARY, J_BOUNDTIGHTENING,"------------------\n");
00242
00243 if (!retval) Jnlst()->Printf(J_ITERSUMMARY, J_BOUNDTIGHTENING,
00244 "Couenne infeasible node from aggressive BT\n");
00245
00246 int objind = Obj (0) -> Body () -> Index ();
00247
00248 Jnlst()->Printf(J_ITERSUMMARY, J_BOUNDTIGHTENING,
00249 "-------------\ndone Aggressive BT. Current bound = %g, cutoff = %g, %d vars\n",
00250 Lb (objind), getCutOff (), ncols);
00251
00252 if (Jnlst()->ProduceOutput(J_DETAILED, J_BOUNDTIGHTENING))
00253 for (int i=0; i<nOrigVars_; i++)
00254 printf(" x%02d [%+20g %+20g] | %+20g\n",
00255 i, Lb (i), Ub (i), X [i]);
00256
00257 if (Jnlst()->ProduceOutput(J_MOREDETAILED, J_BOUNDTIGHTENING))
00258 for (int i=nOrigVars_; i<ncols; i++)
00259 printf (" w%02d [%+20g %+20g] | %+20g\n", i, Lb (i), Ub (i), X [i]);
00260 }
00261
00262 delete [] X;
00263 delete [] f_chg;
00264 delete [] olb;
00265 delete [] oub;
00266
00267 return retval;
00268
00269 }