EvolvingObjects
eoReduceSplit.h
00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
00002 
00003 //-----------------------------------------------------------------------------
00004 // eoReduceSplit.h
00005 //   Base class for population-reducing classes - retaining the poor losers
00006 // (c) GeNeura Team, 1998, Marc Schoenauer, 2002
00007 /*
00008    This library is free software; you can redistribute it and/or
00009    modify it under the terms of the GNU Lesser General Public
00010    License as published by the Free Software Foundation; either
00011    version 2 of the License, or (at your option) any later version.
00012 
00013    This library is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016    Lesser General Public License for more details.
00017 
00018    You should have received a copy of the GNU Lesser General Public
00019    License along with this library; if not, write to the Free Software
00020    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 
00022    Contact: Marc.Schoenauer@inria.fr
00023  */
00024 //-----------------------------------------------------------------------------
00025 
00026 #ifndef eoReduceSplit_h
00027 #define eoReduceSplit_h
00028 
00029 //-----------------------------------------------------------------------------
00030 
00031 #include <iostream>
00032 
00033 // EO includes
00034 #include <eoPop.h>     // eoPop
00035 #include <eoFunctor.h>  // eoReduce
00036 #include <utils/selectors.h>
00037 
00046 template<class EOT> class eoReduceSplit: public eoBF<eoPop<EOT>&, eoPop<EOT> &, void >
00047 {};
00048 
00050 template <class EOT>
00051 class eoTruncateSplit : public eoReduceSplit<EOT>
00052 {
00053 public:
00057   eoTruncateSplit(eoHowMany _howMany, bool _returnEliminated = false):
00058     howMany(_howMany), returnEliminated(_returnEliminated) {}
00059 
00061   void operator()(eoPop<EOT>& _newgen, eoPop<EOT> & _eliminated)
00062   {
00063     unsigned popSize = _newgen.size();
00064     unsigned eliminated = howMany(popSize);
00065     if (!eliminated)   // nothing to do
00066       return ;
00067     unsigned newsize = popSize - eliminated;
00068     if (newsize < 0)
00069       throw std::logic_error("eoTruncateSplit: Cannot truncate to a larger size!\n");
00070 
00071     _newgen.nth_element(newsize);
00072 
00073     // save poor losers if necessary
00074     if (returnEliminated)
00075       for (unsigned i=0; i<eliminated; i++)
00076         _eliminated.push_back(_newgen[newsize+i]);
00077     // truncate
00078     _newgen.resize(newsize);
00079     return ;
00080   }
00081 
00082 private:
00083   eoHowMany howMany;
00084   bool returnEliminated;
00085 };
00086 
00090 template <class EOT>
00091 class eoLinearTruncateSplit : public eoReduceSplit<EOT>
00092 {
00093 public:
00097   eoLinearTruncateSplit(eoHowMany _howMany, bool _returnEliminated = false):
00098     howMany(_howMany), returnEliminated(_returnEliminated) {}
00099 
00101   void operator()(eoPop<EOT>& _newgen, eoPop<EOT> & _eliminated)
00102   {
00103     unsigned popSize = _newgen.size();
00104     unsigned eliminated = howMany(popSize);
00105     if (!eliminated)   // nothing to do
00106       return ;
00107     long newsize = static_cast<long>(popSize) - static_cast<long>(eliminated);
00108     if (newsize < 0)
00109       throw std::logic_error("eoLinearTruncateSplit: Cannot truncate to a larger size!\n");
00110 
00111     _eliminated.reserve(_eliminated.size()+eliminated); //in case not empty?
00112     for (unsigned i=0; i<eliminated; i++)
00113       {
00114         typename eoPop<EOT>::iterator it = _newgen.it_worse_element();
00115         if (returnEliminated)
00116           _eliminated.push_back(*it);
00117         _newgen.erase(it);
00118       }
00119   }
00120 
00121 private:
00122   eoHowMany howMany;
00123   bool returnEliminated;
00124 };
00125 
00127 template <class EOT>
00128 class eoRandomSplit : public eoReduceSplit<EOT>
00129 {
00130 public:
00134   eoRandomSplit(eoHowMany _howMany, bool _returnEliminated = false):
00135     howMany(_howMany), returnEliminated(_returnEliminated) {}
00136 
00138   void operator()(eoPop<EOT>& _newgen, eoPop<EOT> & _eliminated)
00139   {
00140     unsigned popSize = _newgen.size();
00141     unsigned eliminated = howMany(popSize);
00142     if (!eliminated)   // nothing to do
00143       return ;
00144     unsigned newsize = popSize - eliminated;
00145     if (newsize < 0)
00146       throw std::logic_error("eoRandomSplit: Cannot truncate to a larger size!\n");
00147 
00148     _newgen.shuffle();
00149 
00150     // save poor losers if necessary
00151     if (returnEliminated)
00152       for (unsigned i=0; i<eliminated; i++)
00153         _eliminated.push_back(_newgen[newsize+i]);
00154     // truncate
00155     _newgen.resize(newsize);
00156     return ;
00157   }
00158 
00159 private:
00160   eoHowMany howMany;
00161   bool returnEliminated;
00162 };
00163 
00164 
00166 template <class EOT>
00167 class eoLinearRandomSplit : public eoReduceSplit<EOT>
00168 {
00169 public:
00173   eoLinearRandomSplit(eoHowMany _howMany, bool _returnEliminated = false):
00174     howMany(_howMany), returnEliminated(_returnEliminated) {}
00175 
00177   void operator()(eoPop<EOT>& _newgen, eoPop<EOT> & _eliminated)
00178   {
00179     unsigned popSize = _newgen.size();
00180     unsigned eliminated = howMany(popSize);
00181     if (!eliminated)   // nothing to do
00182       return ;
00183     unsigned newsize = popSize - eliminated;
00184     if (newsize < 0)
00185       throw std::logic_error("eoLinearRandomSplit: Cannot truncate to a larger size!\n");
00186 
00187     _eliminated.reserve(_eliminated.size()+eliminated); //in case not empty?
00188     for (unsigned i=0; i<eliminated; i++)
00189       {
00190         unsigned loser=random(_newgen.size());
00191         typename eoPop<EOT>::iterator it = _newgen.begin()+loser;
00192         if (returnEliminated)
00193           _eliminated.push_back(*it);
00194         _newgen.erase(it);
00195       }
00196     return ;
00197   }
00198 
00199 private:
00200   eoHowMany howMany;
00201   bool returnEliminated;
00202 };
00203 
00204 
00208 template <class EOT>
00209 class eoDetTournamentTruncateSplit : public eoReduceSplit<EOT>
00210 {
00211 public:
00215   eoDetTournamentTruncateSplit(unsigned _t_size, eoHowMany _howMany,
00216                       bool _returnEliminated = false):
00217     t_size(_t_size), howMany(_howMany),
00218     returnEliminated(_returnEliminated)
00219   {
00220     if (t_size < 2)
00221       {
00222           eo::log << eo::warnings << "Warning, Size for eoDetTournamentTruncateSplit adjusted to 2" << std::endl;
00223         t_size = 2;
00224       }
00225   }
00226 
00228   void operator()(eoPop<EOT>& _newgen, eoPop<EOT> & _eliminated)
00229   // BUG???  void operator()(eoPop<EOT>& _newgen, unsigned _newsize)
00230   {
00231     unsigned popSize = _newgen.size();
00232     unsigned eliminated = howMany(popSize);
00233     if (!eliminated)   // nothing to do
00234       return ;
00235     unsigned newsize = popSize - eliminated;
00236     if (newsize < 0)
00237       throw std::logic_error("eoDetTournamentTruncateSplit: Cannot truncate to a larger size!\n");
00238 
00239 
00240     _eliminated.reserve(_eliminated.size()+eliminated); //in case not empty?
00241     for (unsigned i=0; i<eliminated; i++)
00242       {
00243         typename eoPop<EOT>::iterator it = inverse_deterministic_tournament(_newgen.begin(), _newgen.end(), t_size);
00244         if (returnEliminated)
00245           _eliminated.push_back(*it);
00246         _newgen.erase(it);
00247       }
00248   }
00249 
00250 private:
00251   unsigned t_size;
00252   eoHowMany howMany;
00253   bool returnEliminated;
00254 };
00255 
00259 template <class EOT>
00260 class eoStochTournamentTruncateSplit : public eoReduce<EOT>
00261 {
00262 public:
00266   eoStochTournamentTruncateSplit(double _t_rate, eoHowMany _howMany,
00267                       bool _returnEliminated = false):
00268     t_rate(_t_rate), howMany(_howMany),
00269     returnEliminated(_returnEliminated)
00270   {
00271     if (t_rate <= 0.5)
00272       {
00273           eo::log << eo::warnings << "Warning, Rate for eoStochTournamentTruncateSplit adjusted to 0.51" << std::endl;
00274         t_rate = 0.51;
00275       }
00276     if (t_rate > 1)
00277       {
00278           eo::log << eo::warnings << "Warning, Rate for eoStochTournamentTruncateSplit adjusted to 1" << std::endl;
00279         t_rate = 1;
00280       }
00281   }
00282 
00284   void operator()(eoPop<EOT>& _newgen, eoPop<EOT> & _eliminated)
00285   //BUG???  void operator()(eoPop<EOT>& _newgen, unsigned _newsize)
00286   {
00287     /* old version
00288     if (!_eliminated.size())       // nothing to do
00289       return;
00290     unsigned oldSize = _newgen.size();
00291     unsigned newSize = oldSize - _eliminated.size();
00292     unsigned eliminated = howMany(popSize);
00293     if (newSize < 0)
00294       throw std::logic_error("eoStochTournamentTruncateSplit: Cannot truncate to a larger size!\n");
00295 
00296 end of old version    */
00297 
00298     unsigned popSize = _newgen.size();
00299     unsigned eliminated = howMany(popSize);
00300     if (!eliminated)   // nothing to do
00301       return ;
00302     unsigned newsize = popSize - eliminated;
00303     if (newsize < 0)
00304       throw std::logic_error("eoDetTournamentTruncateSplit: Cannot truncate to a larger size!\n");
00305 
00306 
00307 
00308     _eliminated.reserve(_eliminated.size()+eliminated); //in case not empty?
00309     for (unsigned i=0; i<_eliminated.size(); i++)
00310       {
00311         typename eoPop<EOT>::iterator it = inverse_stochastic_tournament(_newgen.begin(), _newgen.end(), t_rate);
00312         if (returnEliminated)
00313           _eliminated.push_back(*it);
00314         _newgen.erase(it);
00315       }
00316   }
00317 
00318 
00319 private:
00320   double t_rate;
00321   eoHowMany howMany;
00322   bool returnEliminated;
00323 };
00324 
00325 //-----------------------------------------------------------------------------
00326 
00328 #endif
 All Classes Namespaces Files Functions Variables Typedefs Friends