00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "CoinTime.hpp"
00013 #include "CoinHelperFunctions.hpp"
00014
00015 #include "CouenneProblem.hpp"
00016 #include "CouenneProblemElem.hpp"
00017 #include "CouenneExprVar.hpp"
00018
00019 #include "CouenneRecordBestSol.hpp"
00020
00021 using namespace Couenne;
00022
00023
00024
00025 #define VALID_ONLY_THRESHOLD 5
00026
00033
00034 int CouenneProblem::getIntegerCandidate (const double *xFrac, double *xInt,
00035 double *lb, double *ub) const {
00036 fillIntegerRank ();
00037
00038 if (numberInRank_.size () == 0)
00039 return 0;
00040
00041 CouNumber *store_optimum = optimum_;
00042
00043
00044
00045
00046 optimum_ = NULL;
00047
00048 int
00049 ncols = nVars (),
00050 retval = 0;
00051
00052 double
00053 *olb = new double [ncols], *oub = new double [ncols],
00054 *dualL = new double [nOrigVars_], *dualR = new double [nOrigVars_];
00055
00056
00057 CoinCopyN (Lb (), ncols, olb);
00058 CoinCopyN (Ub (), ncols, oub);
00059
00060
00061 CoinCopyN (xFrac, nOrigVars_ - ndefined_, xInt);
00062
00063 domain_.push (nVars (), xInt, lb, ub);
00064
00065 enum fixType *fixed = new enum fixType [nOrigVars_ - ndefined_];
00066
00067 for (int i=0; i<nOrigVars_ - ndefined_; i++)
00068 fixed [i] = (Var (i) -> isDefinedInteger () &&
00069 Var (i) -> Multiplicity () > 0) ?
00070 UNFIXED : CONTINUOUS;
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 const int infeasible = 1;
00109
00110 try {
00111
00112
00113
00114 jnlst_ -> Printf (Ipopt::J_ERROR, J_NLPHEURISTIC,
00115 "Heuristic: looking for an initial point\n");
00116
00117 if (jnlst_ -> ProduceOutput (Ipopt::J_MOREVECTOR, J_NLPHEURISTIC)) {
00118 printf ("= ===========================================\n");
00119 printf ("= BEGIN ===========================================\n");
00120 printf ("= ===========================================\n");
00121 for (int i=0; i<nOrigVars_; i++)
00122 if (variables_ [i] -> Multiplicity () > 0)
00123 printf ("#### %4d: %d %c %2d frac %20g [%20g,%20g]\n",
00124 i, fixed [i],
00125 variables_ [i] -> isInteger () ? 'I' : ' ',
00126 integerRank_ ? integerRank_ [i] : -1,
00127 xFrac [i], Lb (i), Ub (i));
00128 printf ("---\n");
00129 for (int i=nOrigVars_; i<nVars (); i++)
00130 if (variables_ [i] -> Multiplicity () > 0)
00131 printf ("#### %4d: %c frac %20g [%20g,%20g]\n",
00132 i, variables_ [i] -> isInteger () ? 'I' : ' ',
00133
00134 X (i), Lb (i), Ub (i));
00135 printf ("===================================================\n");
00136 printf ("===================================================\n");
00137 printf ("===================================================\n");
00138 }
00139
00140 const int
00141 N_VARS_HUGE = 10000,
00142 N_VARS_LARGE = 1000,
00143 N_VARS_MEDIUM = 100,
00144 N_VARS_SMALL = 10,
00145 N_VARS_TINY = 5;
00146
00147 int
00148 ntrials = 0,
00149 nvars = nVars (),
00150 maxtrials =
00151 (nvars >= N_VARS_HUGE) ? 0 :
00152 (nvars >= N_VARS_LARGE) ? 1 :
00153 (nvars >= N_VARS_MEDIUM) ? 2 :
00154 (nvars >= N_VARS_SMALL) ? 4 :
00155 (nvars >= N_VARS_TINY) ? 8 : 16;
00156
00157 int rank = 1;
00158
00159 for (std::vector <int>::iterator rNum = numberInRank_.begin();
00160 ++rNum != numberInRank_.end(); rank++)
00161
00162 if (*rNum > 0) {
00163
00164 jnlst_ -> Printf (Ipopt::J_STRONGWARNING, J_NLPHEURISTIC,
00165 "Analyzing %d variables with rank %d\n", *rNum, rank);
00166
00167 if (CoinCpuTime () > maxCpuTime_)
00168 break;
00169
00170
00171
00172
00173 for (int i=0; i<nOrigVars_ - ndefined_; i++)
00174 if ((Var (i) -> Multiplicity () > 0) &&
00175 (Var (i) -> isDefinedInteger ()) &&
00176 (integerRank_ [i] == rank)) {
00177
00178 Lb (i) = CoinMax (Lb (i), floor (xFrac [i] - COUENNE_EPS));
00179 Ub (i) = CoinMin (Ub (i), ceil (xFrac [i] + COUENNE_EPS));
00180 }
00181
00182
00183 initAuxs ();
00184
00185 if (jnlst_ -> ProduceOutput (Ipopt::J_MOREVECTOR, J_NLPHEURISTIC)) {
00186 printf ("= RANK LEVEL = %d [%d] ==================================\n", rank, *rNum);
00187 for (int i=0; i<nOrigVars_; i++)
00188 if (Var (i) -> Multiplicity () > 0)
00189 printf ("#### %4d: %d %c %2d frac %20g -> int %20g [%20g,%20g]\n",
00190 i, fixed [i],
00191 variables_ [i] -> isInteger () ? 'I' : ' ',
00192 integerRank_ ? integerRank_ [i] : -1,
00193 xFrac [i], xInt [i], Lb (i), Ub (i));
00194 printf ("--------------------\n");
00195 for (int i=nOrigVars_; i<nVars (); i++)
00196 if (Var (i) -> Multiplicity () > 0)
00197 printf ("#### %4d: %c frac %20g [%20g,%20g]\n",
00198 i, variables_ [i] -> isInteger () ? 'I' : ' ',
00199
00200 X (i), Lb (i), Ub (i));
00201 printf ("=================================================\n");
00202 }
00203
00204
00205
00206 int remaining = *rNum;
00207
00208 do {
00209
00210 bool one_fixed = false;
00211
00212 for (int i=0; i<nOrigVars_ - ndefined_; i++)
00213
00214 if ((Var (i) -> Multiplicity () > 0) &&
00215 (integerRank_ [i] == rank) &&
00216 (fixed [i] == UNFIXED) &&
00217 Var (i) -> isDefinedInteger ()) {
00218
00219 if (CoinCpuTime () > maxCpuTime_)
00220 break;
00221
00222
00223
00224 if (ceil (Lb (i) - COUENNE_EPS) + COUENNE_EPS >= floor (Ub (i) + COUENNE_EPS)) {
00225
00226 X (i) = Lb (i) = Ub (i) = xInt [i] = ceil (Lb (i) - COUENNE_EPS);
00227 fixed [i] = FIXED;
00228 one_fixed = true;
00229 --remaining;
00230 continue;
00231 }
00232
00233
00234
00235 if (ceil (xInt [i] - COUENNE_EPS) - COUENNE_EPS <= xInt [i]) {
00236
00237 X (i) = Lb (i) = Ub (i) = xInt [i] = ceil (xInt [i] - COUENNE_EPS);
00238 fixed [i] = FIXED;
00239 one_fixed = true;
00240 --remaining;
00241 continue;
00242 }
00243
00244
00245 int result = testIntFix (i, xFrac [i], fixed, xInt,
00246 dualL, dualR, olb, oub, ntrials < maxtrials);
00247
00248 jnlst_ -> Printf (Ipopt::J_STRONGWARNING, J_NLPHEURISTIC,
00249 "testing %d [%g -> %g], res = %d\n", i, xFrac [i], xInt [i], result);
00250
00251 if (result > 0) {
00252 one_fixed = true;
00253 --remaining;
00254 } else if (result < 0)
00255 throw infeasible;
00256 }
00257
00258
00259
00260 if (!one_fixed) {
00261
00262 int index = 0;
00263
00264
00265 while ((index < nOrigVars_ - ndefined_) &&
00266 (!(Var (index) -> isInteger ()) ||
00267 (integerRank_ [index] != rank) ||
00268 (fixed [index] != UNFIXED)))
00269 ++index;
00270
00271 assert (index < nOrigVars_ - ndefined_);
00272
00273 jnlst_ -> Printf (Ipopt::J_MOREVECTOR, J_NLPHEURISTIC,
00274 "none fixed, fix %d from %g [%g,%g] [L=%g, R=%g]",
00275 index, xFrac [index], Lb (index), Ub (index),
00276 dualL [index], dualR [index]);
00277
00278 Lb (index) = Ub (index) = X (index) = xInt [index] =
00279 ((dualL [index] < dualR [index] - COUENNE_EPS) ? floor (xFrac [index]) :
00280 (dualL [index] > dualR [index] + COUENNE_EPS) ? ceil (xFrac [index]) :
00281 ((CoinDrand48 () > xFrac [index] - floor (xFrac [index])) ?
00282 floor (xFrac [index]) : ceil (xFrac [index])));
00283
00284 jnlst_ -> Printf (Ipopt::J_MOREVECTOR, J_NLPHEURISTIC, " to %g\n", xInt [index]);
00285
00286 fixed [index] = FIXED;
00287
00288 --remaining;
00289 }
00290
00291 ntrials++;
00292
00293 if (jnlst_ -> ProduceOutput (Ipopt::J_MOREVECTOR, J_NLPHEURISTIC)) {
00294 printf ("--- remaining = %d --------------------------- \n", remaining);
00295 for (int i=0; i<nOrigVars_; i++)
00296 if (variables_ [i] -> Multiplicity () > 0)
00297 printf ("#### %4d: %d %c %2d frac %20g -> int %20g [%20g,%20g]\n",
00298 i, fixed [i],
00299 variables_ [i] -> isInteger () ? 'I' : ' ',
00300 integerRank_ ? integerRank_ [i] : -1,
00301 xFrac [i], xInt [i], Lb (i), Ub (i));
00302 printf ("---------------------------\n");
00303
00304 }
00305
00306 if (CoinCpuTime () > maxCpuTime_)
00307 break;
00308
00309 } while (remaining > 0);
00310 }
00311
00312
00313 for (int i = nOrigVars_ - ndefined_; i--;)
00314 if (Var (i) -> Multiplicity () > 0) {
00315
00316 if (fixed [i] == FIXED)
00317 lb [i] = ub [i] = X (i) = xInt [i];
00318
00319 else if (Lb (i) > Ub (i)) {
00320 xInt [i] = X (i) = lb [i] = ub [i] =
00321 (fixed [i] == CONTINUOUS) ?
00322 (0.5 * (Lb (i) + Ub (i))) :
00323 COUENNE_round (0.5 * (Lb (i) + Ub (i)));
00324
00325 if (fixed [i] != CONTINUOUS)
00326 fixed [i] = FIXED;
00327
00328 } else {
00329 lb [i] = Lb (i);
00330 ub [i] = Ub (i);
00331 if (xInt [i] < lb [i]) X (i) = xInt [i] = lb [i];
00332 else if (xInt [i] > ub [i]) X (i) = xInt [i] = ub [i];
00333 }
00334 }
00335
00336 restoreUnusedOriginals (xInt);
00337
00338
00339
00340 initAuxs ();
00341 int objind = Obj (0) -> Body () -> Index ();
00342
00343 if (X (objind) < getCutOff ()) {
00344
00345 const CouNumber *x = X ();
00346 CouNumber xp = x [objind];
00347
00348 if
00349 #ifdef FM_CHECKNLP2
00350 (checkNLP2(x, 0, false, true, true, feas_tolerance_))
00351
00352
00353 #else
00354 (checkNLP (x, xp, true))
00355 #endif
00356 {
00357
00358 #ifdef FM_TRACE_OPTSOL
00359 #ifdef FM_CHECKNLP2
00360 recBSol->update();
00361 xp = recBSol->getVal();
00362 #else
00363 recBSol->update(x, nVars(), xp, feas_tolerance_);
00364 #endif
00365 #endif
00366 setCutOff (xp, x);
00367 jnlst_ -> Printf (Ipopt::J_DETAILED, J_NLPHEURISTIC,
00368 "new cutoff from getIntCand: %g\n", xp);
00369 }
00370 }
00371 }
00372
00373 catch (int i) {
00374
00375 if (i == infeasible)
00376 retval = -1;
00377 }
00378
00380
00381 if (jnlst_->ProduceOutput(Ipopt::J_MOREVECTOR, J_NLPHEURISTIC)) {
00382 if (retval >= 0) {
00383 printf ("- Done: retval %d ----------------------------------------------------------------\n",
00384 retval);
00385 for (int i=0; i<nOrigVars_; i++)
00386 if (variables_ [i] -> Multiplicity () > 0)
00387 printf ("#### %4d: %d %c frac %20g -> int %20g [%20g,%20g]\n",
00388 i, fixed [i], variables_ [i] -> isInteger () ? 'I' : ' ',
00389 xFrac [i], xInt [i], lb [i], ub [i]);
00390 } else printf ("no good point was found\n");
00391 }
00392
00393 jnlst_ -> Printf (Ipopt::J_ERROR, J_NLPHEURISTIC, "Heuristic done\n");
00394
00395
00396 delete [] fixed;
00397
00398 delete [] olb; delete [] oub;
00399 delete [] dualL; delete [] dualR;
00400
00401 domain_.pop ();
00402
00403 jnlst_ -> Printf (Ipopt::J_MOREVECTOR, J_NLPHEURISTIC, "Done with GetIntegerCandidate\n");
00404
00405 optimum_ = store_optimum;
00406
00407 return retval;
00408 }