00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef eoReduceSplit_h
00027 #define eoReduceSplit_h
00028
00029
00030
00031 #include <iostream>
00032
00033
00034 #include <eoPop.h>
00035 #include <eoFunctor.h>
00036 #include <utils/selectors.h>
00037
00042 template<class EOT> class eoReduceSplit: public eoBF<eoPop<EOT>&, eoPop<EOT> &, void >
00043 {};
00044
00046 template <class EOT>
00047 class eoTruncateSplit : public eoReduceSplit<EOT>
00048 {
00049 public:
00053 eoTruncateSplit(eoHowMany _howMany, bool _returnEliminated = false):
00054 howMany(_howMany), returnEliminated(_returnEliminated) {}
00055
00057 void operator()(eoPop<EOT>& _newgen, eoPop<EOT> & _eliminated)
00058 {
00059 unsigned popSize = _newgen.size();
00060 unsigned eliminated = howMany(popSize);
00061 if (!eliminated)
00062 return ;
00063 unsigned newsize = popSize - eliminated;
00064 if (newsize < 0)
00065 throw std::logic_error("eoTruncateSplit: Cannot truncate to a larger size!\n");
00066
00067 _newgen.nth_element(newsize);
00068
00069
00070 if (returnEliminated)
00071 for (unsigned i=0; i<eliminated; i++)
00072 _eliminated.push_back(_newgen[newsize+i]);
00073
00074 _newgen.resize(newsize);
00075 return ;
00076 }
00077
00078 private:
00079 eoHowMany howMany;
00080 bool returnEliminated;
00081 };
00082
00086 template <class EOT>
00087 class eoLinearTruncateSplit : public eoReduceSplit<EOT>
00088 {
00089 public:
00093 eoLinearTruncateSplit(eoHowMany _howMany, bool _returnEliminated = false):
00094 howMany(_howMany), returnEliminated(_returnEliminated) {}
00095
00097 void operator()(eoPop<EOT>& _newgen, eoPop<EOT> & _eliminated)
00098 {
00099 unsigned popSize = _newgen.size();
00100 unsigned eliminated = howMany(popSize);
00101 if (!eliminated)
00102 return ;
00103 unsigned newsize = popSize - eliminated;
00104 if (newsize < 0)
00105 throw std::logic_error("eoLinearTruncateSplit: Cannot truncate to a larger size!\n");
00106
00107 _eliminated.reserve(_eliminated.size()+eliminated);
00108 for (unsigned i=0; i<eliminated; i++)
00109 {
00110 typename eoPop<EOT>::iterator it = _newgen.it_worse_element();
00111 if (returnEliminated)
00112 _eliminated.push_back(*it);
00113 _newgen.erase(it);
00114 }
00115 }
00116
00117 private:
00118 eoHowMany howMany;
00119 bool returnEliminated;
00120 };
00121
00123 template <class EOT>
00124 class eoRandomSplit : public eoReduceSplit<EOT>
00125 {
00126 public:
00130 eoRandomSplit(eoHowMany _howMany, bool _returnEliminated = false):
00131 howMany(_howMany), returnEliminated(_returnEliminated) {}
00132
00134 void operator()(eoPop<EOT>& _newgen, eoPop<EOT> & _eliminated)
00135 {
00136 unsigned popSize = _newgen.size();
00137 unsigned eliminated = howMany(popSize);
00138 if (!eliminated)
00139 return ;
00140 unsigned newsize = popSize - eliminated;
00141 if (newsize < 0)
00142 throw std::logic_error("eoRandomSplit: Cannot truncate to a larger size!\n");
00143
00144 _newgen.shuffle();
00145
00146
00147 if (returnEliminated)
00148 for (unsigned i=0; i<eliminated; i++)
00149 _eliminated.push_back(_newgen[newsize+i]);
00150
00151 _newgen.resize(newsize);
00152 return ;
00153 }
00154
00155 private:
00156 eoHowMany howMany;
00157 bool returnEliminated;
00158 };
00159
00160
00162 template <class EOT>
00163 class eoLinearRandomSplit : public eoReduceSplit<EOT>
00164 {
00165 public:
00169 eoLinearRandomSplit(eoHowMany _howMany, bool _returnEliminated = false):
00170 howMany(_howMany), returnEliminated(_returnEliminated) {}
00171
00173 void operator()(eoPop<EOT>& _newgen, eoPop<EOT> & _eliminated)
00174 {
00175 unsigned popSize = _newgen.size();
00176 unsigned eliminated = howMany(popSize);
00177 if (!eliminated)
00178 return ;
00179 unsigned newsize = popSize - eliminated;
00180 if (newsize < 0)
00181 throw std::logic_error("eoLinearRandomSplit: Cannot truncate to a larger size!\n");
00182
00183 _eliminated.reserve(_eliminated.size()+eliminated);
00184 for (unsigned i=0; i<eliminated; i++)
00185 {
00186 unsigned loser=random(_newgen.size());
00187 typename eoPop<EOT>::iterator it = _newgen.begin()+loser;
00188 if (returnEliminated)
00189 _eliminated.push_back(*it);
00190 _newgen.erase(it);
00191 }
00192 return ;
00193 }
00194
00195 private:
00196 eoHowMany howMany;
00197 bool returnEliminated;
00198 };
00199
00200
00204 template <class EOT>
00205 class eoDetTournamentTruncateSplit : public eoReduceSplit<EOT>
00206 {
00207 public:
00211 eoDetTournamentTruncateSplit(unsigned _t_size, eoHowMany _howMany,
00212 bool _returnEliminated = false):
00213 t_size(_t_size), howMany(_howMany),
00214 returnEliminated(_returnEliminated)
00215 {
00216 if (t_size < 2)
00217 {
00218 std::cout << "Warning, Size for eoDetTournamentTruncateSplit adjusted to 2\n";
00219 t_size = 2;
00220 }
00221 }
00222
00224 void operator()(eoPop<EOT>& _newgen, eoPop<EOT> & _eliminated)
00225
00226 {
00227 unsigned popSize = _newgen.size();
00228 unsigned eliminated = howMany(popSize);
00229 if (!eliminated)
00230 return ;
00231 unsigned newsize = popSize - eliminated;
00232 if (newsize < 0)
00233 throw std::logic_error("eoDetTournamentTruncateSplit: Cannot truncate to a larger size!\n");
00234
00235
00236 _eliminated.reserve(_eliminated.size()+eliminated);
00237 for (unsigned i=0; i<eliminated; i++)
00238 {
00239 typename eoPop<EOT>::iterator it = inverse_deterministic_tournament(_newgen.begin(), _newgen.end(), t_size);
00240 if (returnEliminated)
00241 _eliminated.push_back(*it);
00242 _newgen.erase(it);
00243 }
00244 }
00245
00246 private:
00247 unsigned t_size;
00248 eoHowMany howMany;
00249 bool returnEliminated;
00250 };
00251
00255 template <class EOT>
00256 class eoStochTournamentTruncateSplit : public eoReduce<EOT>
00257 {
00258 public:
00262 eoStochTournamentTruncateSplit(double _t_rate, eoHowMany _howMany,
00263 bool _returnEliminated = false):
00264 t_rate(_t_rate), howMany(_howMany),
00265 returnEliminated(_returnEliminated)
00266 {
00267 if (t_rate <= 0.5)
00268 {
00269 std::cout << "Warning, Rate for eoStochTournamentTruncateSplit adjusted to 0.51\n";
00270 t_rate = 0.51;
00271 }
00272 if (t_rate > 1)
00273 {
00274 std::cout << "Warning, Rate for eoStochTournamentTruncateSplit adjusted to 1\n";
00275 t_rate = 1;
00276 }
00277 }
00278
00280 void operator()(eoPop<EOT>& _newgen, eoPop<EOT> & _eliminated)
00281
00282 {
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 unsigned popSize = _newgen.size();
00295 unsigned eliminated = howMany(popSize);
00296 if (!eliminated)
00297 return ;
00298 unsigned newsize = popSize - eliminated;
00299 if (newsize < 0)
00300 throw std::logic_error("eoDetTournamentTruncateSplit: Cannot truncate to a larger size!\n");
00301
00302
00303
00304 _eliminated.reserve(_eliminated.size()+eliminated);
00305 for (unsigned i=0; i<_eliminated.size(); i++)
00306 {
00307 typename eoPop<EOT>::iterator it = inverse_stochastic_tournament(_newgen.begin(), _newgen.end(), t_rate);
00308 if (returnEliminated)
00309 _eliminated.push_back(*it);
00310 _newgen.erase(it);
00311 }
00312 }
00313
00314
00315 private:
00316 double t_rate;
00317 eoHowMany howMany;
00318 bool returnEliminated;
00319 };
00320
00321
00322
00323 #endif