/home/coin/SVN-release/OS-2.2.0/Couenne/src/problem/CouenneSolverInterface.cpp

Go to the documentation of this file.
00001 /* $Id: CouenneSolverInterface.cpp 215 2009-07-08 15:43:38Z pbelotti $
00002  *
00003  * Name:    CouenneSolverInterface.cpp
00004  * Authors: Pietro Belotti, Carnegie Mellon University
00005  *          Andreas Waechter, IBM Corp.
00006  * Purpose: Implementation of the OsiSolverInterface::resolve () method 
00007  *
00008  * (C) Carnegie-Mellon University, 2006-09.
00009  * This file is licensed under the Common Public License (CPL)
00010  */
00011 
00012 #include "CouenneProblem.hpp"
00013 #include "CouenneCutGenerator.hpp"
00014 
00016 template <class T> 
00017 CouenneSolverInterface<T>::CouenneSolverInterface 
00018 (CouenneCutGenerator *cg /*= NULL*/):
00019 
00020   T (),
00021   cutgen_ (cg),
00022   knowInfeasible_(false),
00023   knowOptimal_(false),
00024   knowDualInfeasible_(false) {}
00025 //  doingResolve_ (true) {}
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 //doingResolve_         (src.doingResolve_) {}
00040 
00042 template <class T> 
00043 CouenneSolverInterface<T>::~CouenneSolverInterface () {
00044   //  if (cutgen_)
00045   //    delete cutgen_;
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   // some originals may be unused due to their zero multiplicity (that
00063   // happens when they are duplicates), restore their value
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   // save problem to be loaded later
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   //deleteScaleFactors ();
00116 
00117   // re-solve problem
00118   T::resolve ();
00119 
00120   if (T::getObjValue () <= - Couenne_large_bound)
00121     knowDualInfeasible_ = true;
00122 
00123   CouNumber 
00124     //objval     = T::getObjValue (),
00125     curCutoff  = cutgen_ -> Problem () -> getCutOff (),
00126     objvalGlob = T::getColSolution () [cutgen_ -> Problem () -> Obj (0) -> Body () -> Index ()];  
00127 
00128   // check if resolve found new integer solution
00129   if (//doingResolve () &&                 // this is not called from strong branching
00130       isProvenOptimal () &&
00131       (objvalGlob < curCutoff - COUENNE_EPS) &&
00132       (cutgen_ -> Problem () -> checkNLP (T::getColSolution (), objvalGlob, true)) &&
00133       //      (objvalGlo < curCutoff - COUENNE_EPS) && // check again as it may have changed
00134       (objvalGlob > -COUENNE_INFINITY/2)) {    // check if it makes sense
00135 
00136     // also save the solution so that cbcModel::setBestSolution saves it too
00137 
00138     //printf ("new cutoff from CSI: %g\n", objval);
00139     cutgen_ -> Problem () -> setCutOff (objvalGlob);
00140   }
00141 
00142   // some originals may be unused due to their zero multiplicity (that
00143   // happens when they are duplicates), restore their value
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   // check LP independently
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     //else printf ("Warning: discrepancy between statuses %s -- %s feasible\n", 
00203     //filename, isProvenOptimal () ? "current" : "saved");
00204   }
00205 }
00206 
00207 
00209 template <class T> 
00210 void CouenneSolverInterface<T>::markHotStart () 
00211 {OsiSolverInterface::markHotStart ();} // OsiClpSolverInterface::markHotStart() seems not to work
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   // some originals may be unused due to their zero multiplicity (that
00234   // happens when they are duplicates), restore their value
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 //class CouenneSolverInterface <OsiClpSolverInterface>;

Generated on Thu Aug 5 03:02:57 2010 by  doxygen 1.4.7