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