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