# 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
    00045 template <class EOT>
    00046 class eoPBILAdditive :  public eoDistribUpdater<EOT>
    00047 {
    00048 public:
    00052   eoPBILAdditive(double _LRBest, unsigned _nbBest = 1,
    00053                 double _tolerance=0.0,
    00054                 double _LRWorst = 0.0, unsigned _nbWorst = 0 ) :
    00055     maxBound(1.0-_tolerance), minBound(_tolerance),
    00056     LR(0.0), nbBest(_nbBest), nbWorst(_nbWorst)
    00057   {
    00058     if (nbBest+nbWorst == 0)
    00059       throw std::runtime_error("Must update either from best or from worst in eoPBILAdditive");
    00060
    00061     if (_nbBest)
    00062       {
    00063         lrb = _LRBest/_nbBest;
    00064         LR += _LRBest;
    00065       }
    00066     else
    00067       lrb=0.0;                     // just in case
    00068     if (_nbWorst)
    00069       {
    00070         lrw = _LRWorst/_nbWorst;
    00071         LR += _LRWorst;
    00072       }
    00073     else
    00074       lrw=0.0;                     // just in case
    00075   }
    00076
    00078   virtual void operator()(eoDistribution<EOT> & _distrib, eoPop<EOT>& _pop)
    00079   {
    00080     eoPBILDistrib<EOT>& distrib = dynamic_cast<eoPBILDistrib<EOT>&>(_distrib);
    00081
    00082     std::vector<double> & p = distrib.value();
    00083
    00084     unsigned i, popSize=_pop.size();
    00085     std::vector<const EOT*> result;
    00086     _pop.sort(result);    // is it necessary to sort the whole population?
    00087                          // but I'm soooooooo lazy !!!
    00088
    00089     for (unsigned g=0; g<distrib.size(); g++)
    00090       {
    00091         p[g] *= (1-LR);            // relaxation
    00092         if (nbBest)                // update from some of the best
    00093           for (i=0; i<nbBest; i++)
    00094             {
    00095               const EOT & best = (*result[i]);
    00096               if ( best[g] )       // if 1, increase proba
    00097                 p[g] +=  lrb;
    00098             }
    00099         if (nbWorst)
    00100           for (i=popSize-1; i>=popSize-nbWorst; i--)
    00101             {
    00102               const EOT & best = (*result[i]);
    00103               if ( !best[g] )      // if 0, increase proba
    00104                 p[g] +=  lrw;
    00105             }
    00106         // stay in [0,1] (possibly strictly due to tolerance)
    00107         p[g] = std::min(maxBound, p[g]);
    00108         p[g] = std::max(minBound, p[g]);
    00109       }
    00110   }
    00111
    00112 private:
    00113   double maxBound, minBound;    // proba stay away from 0 and 1 by at least tolerance
    00114   double LR;           // learning rate
    00115   unsigned nbBest;     // number of Best individuals used for update
    00116   unsigned nbWorst;    // number of Worse individuals used for update
    00117   double lrb, lrw;     // "local" learning rates (see operator())
    00118 };
    00119
    00120 #endif