EvolvingObjects
|
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