EvolvingObjects
eoPBILAdditive.h
00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
00002 
00003 //-----------------------------------------------------------------------------
00004 // eoPBILAdditive.h
00005 // (c) Marc Schoenauer, Maarten Keijzer, 2001
00006 /*
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021     Contact: Marc.Schoenauer@polytechnique.fr
00022              mkeijzer@dhi.dk
00023  */
00024 //-----------------------------------------------------------------------------
00025 
00026 #ifndef _eoPBILAdditive_H
00027 #define _eoPBILAdditive_H
00028 
00029 #include <eoDistribUpdater.h>
00030 #include <ga/eoPBILDistrib.h>
00031 
00044 template <class EOT>
00045 class eoPBILAdditive :  public eoDistribUpdater<EOT>
00046 {
00047 public:
00051   eoPBILAdditive(double _LRBest, unsigned _nbBest = 1,
00052                 double _tolerance=0.0,
00053                 double _LRWorst = 0.0, unsigned _nbWorst = 0 ) :
00054     maxBound(1.0-_tolerance), minBound(_tolerance),
00055     LR(0.0), nbBest(_nbBest), nbWorst(_nbWorst)
00056   {
00057     if (nbBest+nbWorst == 0)
00058       throw std::runtime_error("Must update either from best or from worst in eoPBILAdditive");
00059 
00060     if (_nbBest)
00061       {
00062         lrb = _LRBest/_nbBest;
00063         LR += _LRBest;
00064       }
00065     else
00066       lrb=0.0;                     // just in case
00067     if (_nbWorst)
00068       {
00069         lrw = _LRWorst/_nbWorst;
00070         LR += _LRWorst;
00071       }
00072     else
00073       lrw=0.0;                     // just in case
00074   }
00075 
00077   virtual void operator()(eoDistribution<EOT> & _distrib, eoPop<EOT>& _pop)
00078   {
00079     eoPBILDistrib<EOT>& distrib = dynamic_cast<eoPBILDistrib<EOT>&>(_distrib);
00080 
00081     std::vector<double> & p = distrib.value();
00082 
00083     unsigned i, popSize=_pop.size();
00084     std::vector<const EOT*> result;
00085     _pop.sort(result);    // is it necessary to sort the whole population?
00086                          // but I'm soooooooo lazy !!!
00087 
00088     for (unsigned g=0; g<distrib.size(); g++)
00089       {
00090         p[g] *= (1-LR);            // relaxation
00091         if (nbBest)                // update from some of the best
00092           for (i=0; i<nbBest; i++)
00093             {
00094               const EOT & best = (*result[i]);
00095               if ( best[g] )       // if 1, increase proba
00096                 p[g] +=  lrb;
00097             }
00098         if (nbWorst)
00099           for (i=popSize-1; i>=popSize-nbWorst; i--)
00100             {
00101               const EOT & best = (*result[i]);
00102               if ( !best[g] )      // if 0, increase proba
00103                 p[g] +=  lrw;
00104             }
00105         // stay in [0,1] (possibly strictly due to tolerance)
00106         p[g] = std::min(maxBound, p[g]);
00107         p[g] = std::max(minBound, p[g]);
00108       }
00109   }
00110 
00111 private:
00112   double maxBound, minBound;    // proba stay away from 0 and 1 by at least tolerance
00113   double LR;           // learning rate
00114   unsigned nbBest;     // number of Best individuals used for update
00115   unsigned nbWorst;    // number of Worse individuals used for update
00116   double lrb, lrw;     // "local" learning rates (see operator())
00117 };
00118 
00119 #endif
 All Classes Namespaces Files Functions Variables Typedefs Friends