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 eoReduce_h
00027 #define eoReduce_h
00028
00029
00030
00031 #include <iostream>
00032
00033
00034 #include <eoPop.h>
00035 #include <eoFunctor.h>
00036 #include <utils/selectors.h>
00037
00045 template<class EOT> class eoReduce: public eoBF<eoPop<EOT>&, unsigned, void>
00046 {};
00047
00049 template <class EOT> class eoTruncate : public eoReduce<EOT>
00050 {
00051 void operator()(eoPop<EOT>& _newgen, unsigned _newsize)
00052 {
00053 if (_newgen.size() == _newsize)
00054 return;
00055 if (_newgen.size() < _newsize)
00056 throw std::logic_error("eoTruncate: Cannot truncate to a larger size!\n");
00057
00058 _newgen.sort();
00059 _newgen.resize(_newsize);
00060 }
00061 };
00062
00064 template <class EOT> class eoRandomReduce : public eoReduce<EOT>
00065 {
00066 void operator()(eoPop<EOT>& _newgen, unsigned _newsize)
00067 {
00068 if (_newgen.size() == _newsize)
00069 return;
00070 if (_newgen.size() < _newsize)
00071 throw std::logic_error("eoRandomReduce: Cannot truncate to a larger size!\n");
00072
00073
00074 _newgen.shuffle();
00075 _newgen.resize(_newsize);
00076 }
00077 };
00078
00083 template <class EOT> class eoEPReduce : public eoReduce<EOT>
00084 {
00085 public:
00086 typedef typename EOT::Fitness Fitness;
00087
00088 eoEPReduce(unsigned _t_size ):
00089 t_size(_t_size)
00090 {
00091 if (t_size < 2)
00092 {
00093 std::cout << "Warning: EP tournament size should be >= 2. Adjusted" << std::endl;
00094 t_size = 2;
00095 }
00096 }
00097
00099
00100
00101 typedef std::pair<float, typename eoPop<EOT>::iterator> EPpair;
00102 struct Cmp {
00103 bool operator()(const EPpair a, const EPpair b) const
00104 {
00105 if (b.first == a.first)
00106 return (*b.second < *a.second);
00107 return b.first < a.first;
00108 }
00109 };
00110
00111
00112 void operator()(eoPop<EOT>& _newgen, unsigned _newsize)
00113 {
00114 unsigned int presentSize = _newgen.size();
00115
00116 if (presentSize == _newsize)
00117 return;
00118 if (presentSize < _newsize)
00119 throw std::logic_error("eoTruncate: Cannot truncate to a larger size!\n");
00120 std::vector<EPpair> scores(presentSize);
00121 for (unsigned i=0; i<presentSize; i++)
00122 {
00123 scores[i].second = _newgen.begin()+i;
00124 Fitness fit = _newgen[i].fitness();
00125 for (unsigned itourn = 0; itourn < t_size; ++itourn)
00126 {
00127 const EOT & competitor = _newgen[rng.random(presentSize)];
00128 if (fit > competitor.fitness())
00129 scores[i].first += 1;
00130 else if (fit == competitor.fitness())
00131 scores[i].first += 0.5;
00132 }
00133 }
00134
00135
00136 typename std::vector<EPpair>::iterator it = scores.begin() + _newsize;
00137 std::nth_element(scores.begin(), it, scores.end(), Cmp());
00138
00139 unsigned j;
00140
00141
00142
00143
00144
00145 eoPop<EOT> tmPop;
00146 for (j=0; j<_newsize; j++)
00147 {
00148 tmPop.push_back(*scores[j].second);
00149 }
00150 _newgen.swap(tmPop);
00151
00152
00153
00154
00155
00156
00157
00158 }
00159 private:
00160 unsigned t_size;
00161 };
00162
00166 template <class EOT>
00167 class eoLinearTruncate : public eoReduce<EOT>
00168 {
00169 void operator()(eoPop<EOT>& _newgen, unsigned _newsize)
00170 {
00171 unsigned oldSize = _newgen.size();
00172 if (oldSize == _newsize)
00173 return;
00174 if (oldSize < _newsize)
00175 throw std::logic_error("eoLinearTruncate: Cannot truncate to a larger size!\n");
00176 for (unsigned i=0; i<oldSize - _newsize; i++)
00177 {
00178 typename eoPop<EOT>::iterator it = _newgen.it_worse_element();
00179 _newgen.erase(it);
00180 }
00181 }
00182 };
00183
00187 template <class EOT>
00188 class eoDetTournamentTruncate : public eoReduce<EOT>
00189 {
00190 public:
00191 eoDetTournamentTruncate(unsigned _t_size):
00192 t_size(_t_size)
00193 {
00194 if (t_size < 2)
00195 {
00196 std::cout << "Warning, Size for eoDetTournamentTruncate adjusted to 2\n";
00197 t_size = 2;
00198 }
00199 }
00200
00201 void operator()(eoPop<EOT>& _newgen, unsigned _newsize)
00202 {
00203 unsigned oldSize = _newgen.size();
00204 if (_newsize == 0)
00205 {
00206 _newgen.resize(0);
00207 return;
00208 }
00209 if (oldSize == _newsize)
00210 return;
00211 if (oldSize < _newsize)
00212 throw std::logic_error("eoDetTournamentTruncate: Cannot truncate to a larger size!\n");
00213
00214
00215 for (unsigned i=0; i<oldSize - _newsize; i++)
00216 {
00217
00218
00219
00220
00221
00222
00223
00224 _newgen.erase( inverse_deterministic_tournament(_newgen.begin(), _newgen.end(), t_size) );
00225
00226 }
00227 }
00228 private:
00229 unsigned t_size;
00230 };
00231
00235 template <class EOT>
00236 class eoStochTournamentTruncate : public eoReduce<EOT>
00237 {
00238 public:
00239 eoStochTournamentTruncate(double _t_rate):
00240 t_rate(_t_rate)
00241 {
00242 if (t_rate <= 0.5)
00243 {
00244 std::cout << "Warning, Rate for eoStochTournamentTruncate adjusted to 0.51\n";
00245 t_rate = 0.51;
00246 }
00247 if (t_rate > 1)
00248 {
00249 std::cout << "Warning, Rate for eoStochTournamentTruncate adjusted to 1\n";
00250 t_rate = 1;
00251 }
00252 }
00253
00254 void operator()(eoPop<EOT>& _newgen, unsigned _newsize)
00255 {
00256 unsigned oldSize = _newgen.size();
00257 if (_newsize == 0)
00258 {
00259 _newgen.resize(0);
00260 return;
00261 }
00262 if (oldSize == _newsize)
00263 return;
00264 if (oldSize < _newsize)
00265 throw std::logic_error("eoStochTournamentTruncate: Cannot truncate to a larger size!\n");
00266
00267 for (unsigned i=0; i<oldSize - _newsize; i++)
00268 {
00269
00270
00271
00272
00273
00274
00275
00276 _newgen.erase( inverse_stochastic_tournament(_newgen.begin(), _newgen.end(), t_rate) );
00277
00278
00279 }
00280 }
00281
00282 private:
00283 double t_rate;
00284 };
00285
00286
00287
00288 #endif