00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "OsiClpSolverInterface.hpp"
00013 #include "CouenneProblem.hpp"
00014 #include "CouenneSolverInterface.hpp"
00015 #include "CglTreeInfo.hpp"
00016
00018 CouenneSolverInterface::CouenneSolverInterface (CouenneCutGenerator *cg ):
00019
00020 OsiClpSolverInterface(),
00021 cutgen_ (cg),
00022 knowInfeasible_(false),
00023 knowOptimal_(false),
00024 knowDualInfeasible_(false),
00025 doingResolve_ (true) {
00026
00027
00028 if (cutgen_ && !(cutgen_ -> enableLpImpliedBounds ()))
00029 specialOptions_ = specialOptions_ | 262144;
00030 }
00031
00033 CouenneSolverInterface::CouenneSolverInterface (const CouenneSolverInterface &src):
00034
00035 OsiSolverInterface (src),
00036 OsiClpSolverInterface (src),
00037 cutgen_ (src.cutgen_),
00038 knowInfeasible_ (src.knowInfeasible_),
00039 knowOptimal_ (src.knowOptimal_),
00040 knowDualInfeasible_ (src.knowDualInfeasible_),
00041 doingResolve_ (src.doingResolve_) {}
00042
00044 CouenneSolverInterface::~CouenneSolverInterface () {
00045
00046
00047 }
00048
00049
00051 void CouenneSolverInterface::initialSolve () {
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 knowInfeasible_ =
00062 knowOptimal_ =
00063 knowDualInfeasible_ = false;
00064
00065 OsiClpSolverInterface::initialSolve ();
00066
00067
00068 if (getObjValue () <= - Couenne_large_bound)
00069 knowDualInfeasible_ = true;
00070
00071
00072
00073 if (cutgen_ -> Problem () -> nUnusedOriginals () > 0) {
00074 CouNumber *x = new CouNumber [getNumCols ()];
00075 CoinCopyN (getColSolution (), getNumCols (), x);
00076 cutgen_ -> Problem () -> restoreUnusedOriginals (x);
00077 setColSolution (x);
00078 delete [] x;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 }
00095
00096 bool CouenneSolverInterface::isProvenPrimalInfeasible() const {
00097 return knowInfeasible_ || OsiClpSolverInterface::isProvenPrimalInfeasible();
00098 }
00099
00100 bool CouenneSolverInterface::isProvenOptimal() const {
00101 return knowOptimal_ || OsiClpSolverInterface::isProvenOptimal();
00102 }
00103
00104 bool CouenneSolverInterface::isProvenDualInfeasible() const {
00105 return knowDualInfeasible_ || OsiClpSolverInterface::isProvenDualInfeasible();
00106 }
00107
00109 void sparse2dense (int, t_chg_bounds *, int *&, int &);
00110
00111
00113 void CouenneSolverInterface::resolve () {
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00140
00141 static int count = -1;
00142 char filename [30];
00143
00144
00145 if (cutgen_ && (cutgen_ -> check_lp ())) {
00146 count++;
00147 sprintf (filename, "resolve_%d", count);
00148 writeMps (filename);
00149 }
00150
00151 knowInfeasible_ =
00152 knowOptimal_ =
00153 knowDualInfeasible_ = false;
00154
00155 const CoinWarmStart *ws = NULL;
00156
00157 if (cutgen_ && (cutgen_ -> check_lp ()))
00158 ws = getWarmStart ();
00159
00160
00161
00162
00163 OsiClpSolverInterface::resolve ();
00164
00165 if (getObjValue () <= - Couenne_large_bound)
00166 knowDualInfeasible_ = true;
00167
00168 CouNumber objval = getObjValue (),
00169 curCutoff = cutgen_ -> Problem () -> getCutOff ();
00170
00171
00172 if (doingResolve () &&
00173 isProvenOptimal () &&
00174 (objval < curCutoff - COUENNE_EPS) &&
00175 (cutgen_ -> Problem () -> checkNLP (getColSolution (), objval, true)) &&
00176 (objval < curCutoff - COUENNE_EPS) &&
00177 (objval > -COUENNE_INFINITY/2)) {
00178
00179
00180
00181
00182 cutgen_ -> Problem () -> setCutOff (objval);
00183 }
00184
00185
00186
00187 if (cutgen_ -> Problem () -> nUnusedOriginals () > 0) {
00188 CouNumber *x = new CouNumber [getNumCols ()];
00189 CoinCopyN (getColSolution (), getNumCols (), x);
00190 cutgen_ -> Problem () -> restoreUnusedOriginals (x);
00191 setColSolution (x);
00192 delete [] x;
00193 }
00194
00195
00196
00197
00198 if (cutgen_ && (cutgen_ -> check_lp ())) {
00199
00200 OsiSolverInterface
00201 *nsi = new OsiClpSolverInterface,
00202 *csi = clone ();
00203
00204 sprintf (filename, "resolve_%d.mps", count);
00205 nsi -> readMps (filename);
00206
00207 nsi -> messageHandler () -> setLogLevel (0);
00208 nsi -> setWarmStart (ws);
00209
00210 nsi -> initialSolve ();
00211
00212 if ((nsi -> isProvenOptimal () && isProvenOptimal ()) ||
00213 !(nsi -> isProvenOptimal ()) && !isProvenOptimal ()) {
00214
00215 if (nsi -> isProvenOptimal () &&
00216 (fabs (nsi -> getObjValue () - getObjValue ()) /
00217 (1. + fabs (nsi -> getObjValue ()) + fabs (getObjValue ())) > 1e-2))
00218
00219 printf ("Warning: discrepancy between saved %g and current %g [%g], file %s\n",
00220 nsi -> getObjValue (), getObjValue (),
00221 nsi -> getObjValue () - getObjValue (),
00222 filename);
00223 }
00224
00225 csi -> messageHandler () -> setLogLevel (0);
00226 csi -> setWarmStart (ws);
00227
00228 csi -> initialSolve ();
00229
00230 if ((csi -> isProvenOptimal () && isProvenOptimal ()) ||
00231 !(csi -> isProvenOptimal ()) && !isProvenOptimal ()) {
00232
00233 if (csi -> isProvenOptimal () &&
00234 (fabs (csi -> getObjValue () - getObjValue ()) /
00235 (1. + fabs (csi -> getObjValue ()) + fabs (getObjValue ())) > 1e-2))
00236
00237 printf ("Warning: discrepancy between cloned %g and current %g [%g]\n",
00238 csi -> getObjValue (), getObjValue (),
00239 csi -> getObjValue () - getObjValue ());
00240 }
00241
00242 delete nsi;
00243 delete csi;
00244
00245 delete ws;
00246
00247
00248
00249 }
00250 }
00251
00252
00254 void CouenneSolverInterface::markHotStart () {
00255
00256
00257 OsiSolverInterface::markHotStart ();
00258 }
00259
00260
00262 void CouenneSolverInterface::unmarkHotStart() {
00263
00264 OsiSolverInterface::unmarkHotStart();
00265 }
00266
00267
00268
00270 void CouenneSolverInterface::solveFromHotStart() {
00271
00272
00273
00274
00275 knowInfeasible_ =
00276 knowOptimal_ =
00277 knowDualInfeasible_ = false;
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 resolve();
00361
00362 if (getObjValue () <= - Couenne_large_bound)
00363 knowDualInfeasible_ = true;
00364
00365
00366
00367 if (cutgen_ -> Problem () -> nUnusedOriginals () > 0) {
00368 CouNumber *x = new CouNumber [getNumCols ()];
00369 CoinCopyN (getColSolution (), getNumCols (), x);
00370 cutgen_ -> Problem () -> restoreUnusedOriginals (x);
00371 setColSolution (x);
00372 delete [] x;
00373 }
00374
00375 if (isProvenPrimalInfeasible ()) knowInfeasible_ = true;
00376 if (isProvenOptimal ()) knowOptimal_ = true;
00377 if (isProvenDualInfeasible ()) knowDualInfeasible_ = true;
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 }