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
00027 #ifndef _eoStat_h
00028 #define _eoStat_h
00029
00030 #include <numeric>
00031
00032 #include <eoFunctor.h>
00033 #include <utils/eoParam.h>
00034 #include <eoPop.h>
00035 #include <eoParetoFitness.h>
00036
00044 template <class EOT>
00045 class eoStatBase : public eoUF<const eoPop<EOT>&, void>
00046 {
00047 public:
00048 virtual void lastCall(const eoPop<EOT>&) {}
00049 virtual std::string className(void) const { return "eoStatBase"; }
00050 };
00051
00057 template <class EOT, class T>
00058 class eoStat : public eoValueParam<T>, public eoStatBase<EOT>
00059 {
00060 public:
00061
00062 eoStat(T _value, std::string _description)
00063 : eoValueParam<T>(_value, _description)
00064 {}
00065
00066 virtual std::string className(void) const
00067 { return "eoStat"; }
00068 };
00069
00070
00071
00075 template <class EOT>
00076 class eoSortedStatBase : public eoUF<const std::vector<const EOT*>&, void>
00077 {
00078 public:
00079 virtual void lastCall(const std::vector<const EOT*>&) {}
00080 virtual std::string className(void) const { return "eoSortedStatBase"; }
00081 };
00082
00088 template <class EOT, class ParamType>
00089 class eoSortedStat : public eoSortedStatBase<EOT>, public eoValueParam<ParamType>
00090 {
00091 public :
00092 eoSortedStat(ParamType _value, std::string _desc) : eoValueParam<ParamType>(_value, _desc) {}
00093 virtual std::string className(void) const { return "eoSortedStat"; }
00094 };
00095
00105 #ifdef _MSC_VER
00106 template <class EOT> class eoAverageStat : public eoStat<EOT, EOT::Fitness>
00107 #else
00108 template <class EOT> class eoAverageStat : public eoStat<EOT, typename EOT::Fitness>
00109 #endif
00110 {
00111 public :
00112
00113 using eoStat<EOT, typename EOT::Fitness>::value;
00114
00115 typedef typename EOT::Fitness Fitness;
00116
00117 eoAverageStat(std::string _description = "Average Fitness")
00118 : eoStat<EOT, Fitness>(Fitness(), _description) {}
00119
00120 static Fitness sumFitness(double _sum, const EOT& _eot){
00121 _sum += _eot.fitness();
00122 return _sum;
00123 }
00124
00125 eoAverageStat(double _value, std::string _desc) : eoStat<EOT, double>(_value, _desc) {}
00126
00127 virtual void operator()(const eoPop<EOT>& _pop){
00128 doit(_pop, Fitness());
00129 }
00130
00131 virtual std::string className(void) const { return "eoAverageStat"; }
00132
00133 private :
00134
00135
00136 template <class T>
00137 void doit(const eoPop<EOT>& _pop, eoParetoFitness<T>)
00138 {
00139 value().clear();
00140 value().resize(_pop[0].fitness().size(), 0.0);
00141
00142 for (unsigned o = 0; o < value().size(); ++o)
00143 {
00144 for (unsigned i = 0; i < _pop.size(); ++i)
00145 {
00146 value()[o] += _pop[i].fitness()[o];
00147 }
00148
00149 value()[o] /= _pop.size();
00150 }
00151 }
00152
00153
00154 template <class T>
00155 void doit(const eoPop<EOT>& _pop, T)
00156 {
00157 Fitness v = std::accumulate(_pop.begin(), _pop.end(), Fitness(0.0), eoAverageStat::sumFitness);
00158
00159 value() = v / _pop.size();
00160 }
00161
00162 };
00163
00167 template <class EOT>
00168 class eoSecondMomentStats : public eoStat<EOT, std::pair<double, double> >
00169 {
00170 public :
00171
00172 using eoStat<EOT, std::pair<double, double> >::value;
00173
00174 typedef typename EOT::Fitness fitness_type;
00175
00176 typedef std::pair<double, double> SquarePair;
00177
00178 eoSecondMomentStats(std::string _description = "Average & Stdev")
00179 : eoStat<EOT, SquarePair>(std::make_pair(0.0,0.0), _description)
00180 {}
00181
00182 static SquarePair sumOfSquares(SquarePair _sq, const EOT& _eo)
00183 {
00184 double fitness = _eo.fitness();
00185
00186 _sq.first += fitness;
00187 _sq.second += fitness * fitness;
00188 return _sq;
00189 }
00190
00191 virtual void operator()(const eoPop<EOT>& _pop)
00192 {
00193 SquarePair result = std::accumulate(_pop.begin(), _pop.end(), std::make_pair(0.0, 0.0), eoSecondMomentStats::sumOfSquares);
00194
00195 double n = _pop.size();
00196 value().first = result.first / n;
00197 value().second = sqrt( (result.second - n * value().first * value().first) / (n - 1.0));
00198 }
00199
00200 virtual std::string className(void) const { return "eoSecondMomentStats"; }
00201 };
00202
00206 #ifdef _MSC_VER
00207 template <class EOT>
00208 class eoNthElementFitnessStat : public eoSortedStat<EOT, EOT::Fitness >
00209 #else
00210 template <class EOT>
00211 class eoNthElementFitnessStat : public eoSortedStat<EOT, typename EOT::Fitness >
00212 #endif
00213 {
00214 public :
00215 using eoSortedStat<EOT, typename EOT::Fitness >::value;
00216
00217 typedef typename EOT::Fitness Fitness;
00218
00219 eoNthElementFitnessStat(unsigned _whichElement, std::string _description = "nth element fitness")
00220 : eoSortedStat<EOT, Fitness>(Fitness(), _description), whichElement(_whichElement) {}
00221
00222 virtual void operator()(const std::vector<const EOT*>& _pop)
00223 {
00224 if (whichElement > _pop.size())
00225 throw std::logic_error("fitness requested of element outside of pop");
00226
00227 doit(_pop, Fitness());
00228 }
00229
00230 virtual std::string className(void) const { return "eoNthElementFitnessStat"; }
00231 private :
00232
00233 struct CmpFitness
00234 {
00235 CmpFitness(unsigned _whichElement, bool _maxim) : whichElement(_whichElement), maxim(_maxim) {}
00236
00237 bool operator()(const EOT* a, const EOT* b)
00238 {
00239 if (maxim)
00240 return a->fitness()[whichElement] > b->fitness()[whichElement];
00241
00242 return a->fitness()[whichElement] < b->fitness()[whichElement];
00243 }
00244
00245 unsigned whichElement;
00246 bool maxim;
00247 };
00248
00249
00250 template <class T>
00251 void doit(const eoPop<EOT>& _pop, eoParetoFitness<T>)
00252 {
00253 typedef typename EOT::Fitness::fitness_traits traits;
00254
00255 value().resize(traits::nObjectives());
00256
00257
00258 std::vector<const EOT*> tmp_pop = _pop;
00259
00260 for (unsigned o = 0; o < value().size(); ++o)
00261 {
00262 typename std::vector<const EOT*>::iterator nth = tmp_pop.begin() + whichElement;
00263 std::nth_element(tmp_pop.begin(), nth, tmp_pop.end(), CmpFitness(o, traits::maximizing(o)));
00264 value()[o] = (*nth)->fitness()[o];
00265 }
00266 }
00267
00268
00269 template <class T>
00270 void doit(const std::vector<const EOT*>& _pop, T)
00271 {
00272 value() = _pop[whichElement]->fitness();
00273 }
00274
00275 unsigned whichElement;
00276 };
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00311 #ifdef _MSC_VER
00312 template <class EOT>
00313 class eoBestFitnessStat : public eoStat<EOT, EOT::Fitness>
00314 #else
00315 template <class EOT>
00316 class eoBestFitnessStat : public eoStat<EOT, typename EOT::Fitness>
00317 #endif
00318 {
00319 public:
00320
00321 using eoStat<EOT, typename EOT::Fitness>::value;
00322
00323 typedef typename EOT::Fitness Fitness;
00324
00325 eoBestFitnessStat(std::string _description = "Best ")
00326 : eoStat<EOT, Fitness>(Fitness(), _description)
00327 {}
00328
00329 void operator()(const eoPop<EOT>& _pop) {
00330 doit(_pop, Fitness() );
00331 }
00332
00333 virtual std::string className(void) const { return "eoBestFitnessStat"; }
00334
00335
00336 private :
00337
00338 struct CmpFitness
00339 {
00340 CmpFitness(unsigned _which, bool _maxim) : which(_which), maxim(_maxim) {}
00341
00342 bool operator()(const EOT& a, const EOT& b)
00343 {
00344 if (maxim)
00345 return a.fitness()[which] < b.fitness()[which];
00346
00347 return a.fitness()[which] > b.fitness()[which];
00348 }
00349
00350 unsigned which;
00351 bool maxim;
00352 };
00353
00354
00355 template <class T>
00356 void doit(const eoPop<EOT>& _pop, eoParetoFitness<T>)
00357 {
00358 typedef typename EOT::Fitness::fitness_traits traits;
00359 value().resize(traits::nObjectives());
00360
00361 for (unsigned o = 0; o < traits::nObjectives(); ++o)
00362 {
00363 typename eoPop<EOT>::const_iterator it = std::max_element(_pop.begin(), _pop.end(), CmpFitness(o, traits::maximizing(o)));
00364 value()[o] = it->fitness()[o];
00365 }
00366 }
00367
00368
00369 template<class T>
00370 void doit(const eoPop<EOT>& _pop, T)
00371 {
00372 value() = _pop.best_element().fitness();
00373 }
00374
00375 };
00376
00377 template <class EOT>
00378 class eoDistanceStat : public eoStat<EOT, double>
00379 {
00380 public:
00381
00382 using eoDistanceStat< EOT >::value;
00383
00384 eoDistanceStat(std::string _name = "distance")
00385 : eoStat<EOT, double>(0.0, _name)
00386 {}
00387
00388 template <class T>
00389 double distance(T a, T b)
00390 {
00391 T res = a-b;
00392 return res < 0? -res : res;
00393 }
00394
00395 double distance(bool a, bool b)
00396 {
00397 return (a==b)? 0 : 1;
00398 }
00399
00400 void operator()(const eoPop<EOT>& _pop)
00401 {
00402 double& v = value();
00403 v = 0.0;
00404
00405 for (unsigned i = 0; i < _pop.size(); ++i)
00406 {
00407 for (unsigned j = 0; j < _pop.size(); ++j)
00408 {
00409 for (unsigned k = 0; k < _pop[i].size(); ++k)
00410 {
00411 v += distance(_pop[i][k], _pop[j][k]);
00412 }
00413 }
00414 }
00415
00416 double sz = _pop.size();
00417 v /= sz * sz * _pop[0].size();
00418 }
00419 virtual std::string className(void) const { return "eoDistanceStat"; }
00420
00421 };
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 #endif