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 eoProportionalSelect_h
00028 #define eoProportionalSelect_h
00029
00030
00031
00032 #include <utils/eoRNG.h>
00033 #include <utils/selectors.h>
00034 #include <eoSelectOne.h>
00035 #include <eoPop.h>
00036
00043
00044
00045 template <class EOT> class eoProportionalSelect: public eoSelectOne<EOT>
00046 {
00047 public:
00049 eoProportionalSelect(const eoPop<EOT>& pop = eoPop<EOT>())
00050 {
00051 if (minimizing_fitness<EOT>())
00052 throw std::logic_error("eoProportionalSelect: minimizing fitness");
00053 }
00054
00055 void setup(const eoPop<EOT>& _pop)
00056 {
00057 if (_pop.size() == 0) return;
00058
00059 cumulative.resize(_pop.size());
00060 cumulative[0] = _pop[0].fitness();
00061
00062 for (unsigned i = 1; i < _pop.size(); ++i)
00063 {
00064 cumulative[i] = _pop[i].fitness() + cumulative[i-1];
00065 }
00066 }
00067
00070 const EOT& operator()(const eoPop<EOT>& _pop)
00071 {
00072 if (cumulative.size() == 0) setup(_pop);
00073
00074 double fortune = rng.uniform() * cumulative.back();
00075 typename FitVec::iterator result = std::upper_bound(cumulative.begin(), cumulative.end(), fortune);
00076 return _pop[result - cumulative.begin()];
00077 }
00078
00079 private :
00080
00081 typedef std::vector<typename EOT::Fitness> FitVec;
00082 FitVec cumulative;
00083 };
00084
00085 #endif