/home/coin/SVN-release/OS-2.4.2/Couenne/src/heuristics/CouenneFPpool.cpp

Go to the documentation of this file.
00001 /* $Id: CouenneFPpool.cpp 698 2011-06-20 13:36:43Z pbelotti $
00002  *
00003  * Name:    CouenneFPpool.cpp
00004  * Authors: Pietro Belotti
00005  *          Timo Berthold, ZIB Berlin
00006  * Purpose: Pool of MILP- (and why not? NLP-) feasible solutions for
00007  *          restart use in the Feasibility Pump
00008  * 
00009  * This file is licensed under the Eclipse Public License (EPL)
00010  */
00011 
00012 #include "CoinHelperFunctions.hpp"
00013 
00014 #include "CouenneProblem.hpp"
00015 #include "CouenneFPpool.hpp"
00016 #include "CouenneFeasPump.hpp"
00017 #include "CouenneExprVar.hpp"
00018 #include "CouenneExprAux.hpp"
00019 
00020 const double COMP_TOLERANCE = COUENNE_EPS;
00021 
00022 using namespace Couenne;
00023 
00025 CouenneFPsolution::CouenneFPsolution (CouenneProblem *p, CouNumber *x, bool copied):
00026 
00027   x_        (NULL),
00028   n_        (p -> nVars ()),
00029   nNLinf_   (0),
00030   nIinf_    (0),
00031   objVal_   (0.),
00032   maxNLinf_ (0.),
00033   maxIinf_  (0.),
00034   copied_   (copied) {
00035 
00039 
00040   if (copied_) {
00041     x_ = x;
00042     return;
00043   }
00044 
00045   x_ = CoinCopyOfArray (x, p -> nVars ());
00046 
00047   for (std::vector <exprVar *>::iterator i = p -> Variables (). begin (); 
00048        i != p -> Variables (). end ();
00049        ++i) {
00050 
00051     CouNumber 
00052       vval = (**i) ();
00053 
00054     if ((*i) -> Multiplicity () <= 0)
00055       continue;
00056 
00057     if ((*i) -> isInteger ()) {
00058 
00059       double inf = CoinMax (vval - floor (vval + COUENNE_EPS),
00060                             ceil (vval - COUENNE_EPS) - vval);
00061 
00062       if (inf > COUENNE_EPS) {
00063 
00064         ++nIinf_;
00065  
00066         if (inf > maxIinf_) 
00067           maxIinf_ = inf;
00068       }
00069     }
00070 
00071     if (((*i) -> Type () == AUX) &&
00072         ((*i) -> Image () -> Linearity () > LINEAR)) {
00073 
00074       double 
00075         diff = 0.,
00076         fval = (*((*i) -> Image ())) ();
00077 
00078       if      ((*i) -> sign () != expression::AUX_GEQ) diff = CoinMax (diff, vval - fval);
00079       else if ((*i) -> sign () != expression::AUX_LEQ) diff = CoinMax (diff, fval - vval);
00080 
00081       if (diff > COUENNE_EPS) {
00082 
00083         ++nNLinf_;
00084 
00085         if (diff > maxNLinf_)
00086           maxNLinf_ = diff;
00087       }
00088     }
00089   }
00090 }
00091 
00092 
00095 CouenneFPsolution::CouenneFPsolution (CouNumber *x, 
00096                                       int n, 
00097                                       int nNLinf,
00098                                       int nIinf,
00099                                       CouNumber objVal,
00100                                       CouNumber maxNLinf,
00101                                       CouNumber maxIinf):
00102 
00103   x_          (CoinCopyOfArray (x, n)),
00104   n_          (n),
00105   nNLinf_     (nNLinf),
00106   nIinf_      (nIinf),
00107   objVal_     (objVal),
00108   maxNLinf_   (maxNLinf),
00109   maxIinf_    (maxIinf),
00110   copied_     (false) {}
00111 
00113 CouenneFPsolution::CouenneFPsolution (const CouenneFPsolution &src):
00114   x_          (src.x_ ? CoinCopyOfArray (src.x_, src.n_) : NULL),
00115   n_          (src.n_),
00116   nNLinf_     (src.nNLinf_),
00117   nIinf_      (src.nIinf_),
00118   objVal_     (src.objVal_),
00119   maxNLinf_   (src.maxNLinf_),
00120   maxIinf_    (src.maxIinf_),
00121   copied_     (false) {}
00122 
00123 
00125 CouenneFPsolution &CouenneFPsolution::operator= (const CouenneFPsolution &src) {
00126 
00127   x_         = src.x_ ? CoinCopyOfArray (src.x_, src.n_) : NULL;
00128   n_         = src.n_;
00129   nNLinf_    = src.nNLinf_;
00130   nIinf_     = src.nIinf_;
00131   objVal_    = src.objVal_;
00132   maxNLinf_  = src.maxNLinf_;
00133   maxIinf_   = src.maxIinf_;
00134   copied_    = false;
00135 
00136   return *this;
00137 }
00138 
00140 CouenneFPsolution::~CouenneFPsolution () {
00141 
00142   if (x_ && !copied_)
00143     delete [] x_;
00144 }
00145 
00147 bool CouenneFPsolution::compare (const CouenneFPsolution &other, enum what_to_compare comparedTerm) const {
00148 
00149   switch (comparedTerm) {
00150 
00151   case SUM_NINF: return (nNLinf_   + nIinf_   < other.nNLinf_   + other.nIinf_);
00152   case SUM_INF:  return (maxNLinf_ + maxIinf_ < other.maxNLinf_ + other.maxIinf_);
00153   case OBJVAL:   return (objVal_              < other.objVal_);
00154   }
00155 
00156   printf ("CouenneFPsolution::compare: bad compared term\n");
00157   abort ();
00158 }
00159 
00160 
00162 CouenneFPpool::CouenneFPpool (const CouenneFPpool &src):
00163   set_ (src.set_) {}
00164 
00165 
00167 CouenneFPpool &CouenneFPpool::operator= (const CouenneFPpool &src) {
00168 
00169   set_ = src.set_;
00170 
00171   return *this;
00172 }
00173 
00175 bool compareSol::operator() (const CouenneFPsolution &one, 
00176                              const CouenneFPsolution &two) const {
00177 
00178   register const double
00179     *x1 = one.x (),
00180     *x2 = two.x ();
00181 
00182   register int n = one.n ();
00183 
00184   while (n--)
00185     if ((*x1++ - *x2++) <= COMP_TOLERANCE)
00186       return true;
00187 
00188   return false;
00189 }
00190 
00193 void CouenneFPpool::findClosestAndReplace (double *sol, double *nSol, int nvars)  {
00194 
00195    double bestdist = COIN_DBL_MAX;
00196    std::set <CouenneFPsolution>::iterator bestsol = set_. end ();
00197 
00198    if( nSol )
00199    {
00200       for (std::set <CouenneFPsolution>::iterator i = set_. begin (); 
00201            i != set_. end (); ++i)
00202       {
00203         //compute distance of pool solution and NLP solution
00204 
00205         register double 
00206            dist = 0.0,
00207            delta;
00208 
00209         const register double 
00210           *x = i -> x (),
00211           *s = nSol;
00212 
00213         register bool move_on = false;
00214 
00215         for (int j = nvars; j--;) {
00216 
00217           delta = *x++ - *s++;
00218 
00219           dist += delta * delta;
00220 
00221           if (dist >= bestdist) { // interrupt check of this solution
00222                                   // if already above current best
00223             move_on = true;
00224             break;
00225           }
00226         }
00227 
00228         if (move_on) 
00229           continue;
00230 
00231          //update best solution
00232          if( dist < bestdist )
00233          {
00234             bestdist = dist;
00235             bestsol = i;
00236          }
00237       }   
00238    }
00239    else 
00240       bestsol = set_. begin ();
00241 
00242    if( bestsol != set_. end () )
00243    {
00244       sol = CoinCopyOfArray ((*bestsol).x(), nvars); 
00245       set_. erase(bestsol);
00246    }   
00247 }

Generated on Wed Nov 30 03:04:04 2011 by  doxygen 1.4.7