00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "CouenneProblem.hpp"
00013 #include "CouenneCutGenerator.hpp"
00014
00016 template <class T>
00017 CouenneSolverInterface<T>::CouenneSolverInterface
00018 (CouenneCutGenerator *cg ):
00019
00020 T (),
00021 cutgen_ (cg),
00022 knowInfeasible_(false),
00023 knowOptimal_(false),
00024 knowDualInfeasible_(false) {}
00025
00026
00027
00029 template <class T>
00030 CouenneSolverInterface<T>::CouenneSolverInterface
00031 (const CouenneSolverInterface &src):
00032
00033 OsiSolverInterface (src),
00034 T (src),
00035 cutgen_ (src.cutgen_),
00036 knowInfeasible_ (src.knowInfeasible_),
00037 knowOptimal_ (src.knowOptimal_),
00038 knowDualInfeasible_ (src.knowDualInfeasible_) {}
00039
00040
00042 template <class T>
00043 CouenneSolverInterface<T>::~CouenneSolverInterface () {
00044
00045
00046 }
00047
00048
00050 template <class T>
00051 void CouenneSolverInterface<T>::initialSolve () {
00052
00053 knowInfeasible_ =
00054 knowOptimal_ =
00055 knowDualInfeasible_ = false;
00056
00057 T::initialSolve ();
00058
00059 if (T::getObjValue () <= - Couenne_large_bound)
00060 knowDualInfeasible_ = true;
00061
00062
00063
00064 if (cutgen_ -> Problem () -> nUnusedOriginals () > 0) {
00065 CouNumber *x = new CouNumber [T::getNumCols ()];
00066 CoinCopyN (T::getColSolution (), T::getNumCols (), x);
00067 cutgen_ -> Problem () -> restoreUnusedOriginals (x);
00068 T::setColSolution (x);
00069 delete [] x;
00070 }
00071 }
00072
00073 template <class T>
00074 bool CouenneSolverInterface<T>::isProvenPrimalInfeasible() const {
00075 return knowInfeasible_ || T::isProvenPrimalInfeasible();
00076 }
00077
00078 template <class T>
00079 bool CouenneSolverInterface<T>::isProvenOptimal() const {
00080 return knowOptimal_ || T::isProvenOptimal();
00081 }
00082
00083 template <class T>
00084 bool CouenneSolverInterface<T>::isProvenDualInfeasible() const {
00085 return knowDualInfeasible_ || T::isProvenDualInfeasible();
00086 }
00087
00089 void sparse2dense (int, t_chg_bounds *, int *&, int &);
00090
00091
00093 template <class T>
00094 void CouenneSolverInterface<T>::resolve () {
00095
00096 static int count = -1;
00097 char filename [30];
00098
00099
00100 if (cutgen_ && (cutgen_ -> check_lp ())) {
00101 count++;
00102 sprintf (filename, "resolve_%d", count);
00103 T::writeMps (filename);
00104 }
00105
00106 knowInfeasible_ =
00107 knowOptimal_ =
00108 knowDualInfeasible_ = false;
00109
00110 const CoinWarmStart *ws = NULL;
00111
00112 if (cutgen_ && (cutgen_ -> check_lp ()))
00113 ws = T::getWarmStart ();
00114
00115
00116
00117
00118 T::resolve ();
00119
00120 if (T::getObjValue () <= - Couenne_large_bound)
00121 knowDualInfeasible_ = true;
00122
00123 CouNumber
00124
00125 curCutoff = cutgen_ -> Problem () -> getCutOff (),
00126 objvalGlob = T::getColSolution () [cutgen_ -> Problem () -> Obj (0) -> Body () -> Index ()];
00127
00128
00129 if (
00130 isProvenOptimal () &&
00131 (objvalGlob < curCutoff - COUENNE_EPS) &&
00132 (cutgen_ -> Problem () -> checkNLP (T::getColSolution (), objvalGlob, true)) &&
00133
00134 (objvalGlob > -COUENNE_INFINITY/2)) {
00135
00136
00137
00138
00139 cutgen_ -> Problem () -> setCutOff (objvalGlob);
00140 }
00141
00142
00143
00144 if (cutgen_ -> Problem () -> nUnusedOriginals () > 0) {
00145 CouNumber *x = new CouNumber [T::getNumCols ()];
00146 CoinCopyN (T::getColSolution (), T::getNumCols (), x);
00147 cutgen_ -> Problem () -> restoreUnusedOriginals (x);
00148 T::setColSolution (x);
00149 delete [] x;
00150 }
00151
00152
00153 if (cutgen_ && (cutgen_ -> check_lp ())) {
00154
00155 OsiSolverInterface
00156 *nsi = new T,
00157 *csi = clone ();
00158
00159 sprintf (filename, "resolve_%d.mps", count);
00160 nsi -> readMps (filename);
00161
00162 nsi -> messageHandler () -> setLogLevel (0);
00163 nsi -> setWarmStart (ws);
00164
00165 nsi -> initialSolve ();
00166
00167 if ((nsi -> isProvenOptimal () && isProvenOptimal ()) ||
00168 !(nsi -> isProvenOptimal ()) && !isProvenOptimal ()) {
00169
00170 if (nsi -> isProvenOptimal () &&
00171 (fabs (nsi -> getObjValue () - T::getObjValue ()) /
00172 (1. + fabs (nsi -> getObjValue ()) + fabs (T::getObjValue ())) > 1e-2))
00173
00174 printf ("Warning: discrepancy between saved %g and current %g [%g], file %s\n",
00175 nsi -> getObjValue (), T::getObjValue (),
00176 nsi -> getObjValue () - T::getObjValue (),
00177 filename);
00178 }
00179
00180 csi -> messageHandler () -> setLogLevel (0);
00181 csi -> setWarmStart (ws);
00182
00183 csi -> initialSolve ();
00184
00185 if ((csi -> isProvenOptimal () && isProvenOptimal ()) ||
00186 !(csi -> isProvenOptimal ()) && !isProvenOptimal ()) {
00187
00188 if (csi -> isProvenOptimal () &&
00189 (fabs (csi -> getObjValue () - T::getObjValue ()) /
00190 (1. + fabs (csi -> getObjValue ()) + fabs (T::getObjValue ())) > 1e-2))
00191
00192 printf ("Warning: discrepancy between cloned %g and current %g [%g]\n",
00193 csi -> getObjValue (), T::getObjValue (),
00194 csi -> getObjValue () - T::getObjValue ());
00195 }
00196
00197 delete nsi;
00198 delete csi;
00199
00200 delete ws;
00201
00202
00203
00204 }
00205 }
00206
00207
00209 template <class T>
00210 void CouenneSolverInterface<T>::markHotStart ()
00211 {OsiSolverInterface::markHotStart ();}
00212
00213
00215 template <class T>
00216 void CouenneSolverInterface<T>::unmarkHotStart ()
00217 {OsiSolverInterface::unmarkHotStart();}
00218
00219
00221 template <class T>
00222 void CouenneSolverInterface<T>::solveFromHotStart () {
00223
00224 knowInfeasible_ =
00225 knowOptimal_ =
00226 knowDualInfeasible_ = false;
00227
00228 resolve();
00229
00230 if (T::getObjValue () <= - Couenne_large_bound)
00231 knowDualInfeasible_ = true;
00232
00233
00234
00235 if (cutgen_ -> Problem () -> nUnusedOriginals () > 0) {
00236 CouNumber *x = new CouNumber [T::getNumCols ()];
00237 CoinCopyN (T::getColSolution (), T::getNumCols (), x);
00238 cutgen_ -> Problem () -> restoreUnusedOriginals (x);
00239 T::setColSolution (x);
00240 delete [] x;
00241 }
00242
00243 if (isProvenPrimalInfeasible ()) knowInfeasible_ = true;
00244 if (isProvenOptimal ()) knowOptimal_ = true;
00245 if (isProvenDualInfeasible ()) knowDualInfeasible_ = true;
00246 }
00247
00248