eoPerf2Worth.h

00001 
00025 //-----------------------------------------------------------------------------
00026 
00027 #ifndef eoPerf2Worth_h
00028 #define eoPerf2Worth_h
00029 
00030 #include <utils/eoParam.h>
00031 #include <eoPop.h>
00032 #include <eoFunctor.h>
00033 
00034 #include <algorithm>
00035 #include <vector>
00036 #include <string>
00037 
00042 template <class EOT, class WorthT = double>
00043 class eoPerf2Worth : public eoUF<const eoPop<EOT>&, void>, public eoValueParam<std::vector<WorthT> >
00044 {
00045 public:
00046 
00047     using eoValueParam<std::vector<WorthT> >::value;
00048 
00050     eoPerf2Worth(std::string _description = "Worths")
00051         : eoValueParam<std::vector<WorthT> >(std::vector<WorthT>(0), _description)
00052         {}
00053 
00056   virtual void sort_pop(eoPop<EOT>& _pop)
00057   { // start with a std::vector of indices
00058       std::vector<unsigned> indices(_pop.size());
00059 
00060     unsigned i;
00061     for (i = 0; i < _pop.size();++i)
00062     { // could use generate, but who cares
00063       indices[i] = i;
00064     }
00065 
00066     std::sort(indices.begin(), indices.end(), compare_worth(value()));
00067 
00068     eoPop<EOT>      tmp_pop;
00069     tmp_pop.resize(_pop.size());
00070     std::vector<WorthT>  tmp_worths(value().size());
00071 
00072     for (i = 0; i < _pop.size(); ++i)
00073     {
00074       tmp_pop[i] = _pop[indices[i]];
00075       tmp_worths[i] = value()[indices[i]];
00076     }
00077 
00078     std::swap(_pop, tmp_pop);
00079     std::swap(value(), tmp_worths);
00080   }
00081 
00083     class compare_worth
00084     {
00085     public:
00086 
00087         compare_worth(const std::vector<WorthT>& _worths) : worths(_worths) {}
00088 
00089         bool operator()(unsigned a, unsigned b) const {
00090             return worths[b] < worths[a]; // sort in descending (!) order
00091         }
00092 
00093     private:
00094 
00095         const std::vector<WorthT>& worths;
00096     };
00097 
00098 
00099 
00100     virtual void resize(eoPop<EOT>& _pop, unsigned sz) {
00101         _pop.resize(sz);
00102         value().resize(sz);
00103     };
00104 
00105 };
00106 
00110 template <class EOT, class WorthT = typename EOT::Fitness>
00111 class eoPerf2WorthCached : public eoPerf2Worth<EOT, WorthT>
00112 {
00113 public:
00114 
00115     using eoPerf2Worth<EOT, WorthT>::value;
00116 
00117     eoPerf2WorthCached(std::string _description = "Worths") : eoPerf2Worth<EOT, WorthT>(_description) {}
00118 
00119 
00125   void operator()(const eoPop<EOT>& _pop)
00126   {
00127     unsigned i;
00128       if (fitness_cache.size() == _pop.size())
00129       {
00130         bool in_sync = true;
00131         for (i = 0; i < _pop.size(); ++i)
00132         {
00133           if (fitness_cache[i] != _pop[i].fitness())
00134           {
00135             in_sync = false;
00136             fitness_cache[i] = _pop[i].fitness();
00137           }
00138         }
00139 
00140         if (in_sync)
00141         { // worths are up to date
00142           return;
00143         }
00144       }
00145       else // just cache the fitness
00146       {
00147         fitness_cache.resize(_pop.size());
00148         for (i = 0; i < _pop.size(); ++i)
00149         {
00150           fitness_cache[i] = _pop[i].fitness();
00151         }
00152       }
00153 
00154     // call derived implementation of perf2worth mapping
00155     calculate_worths(_pop);
00156   }
00157 
00159   virtual void calculate_worths(const eoPop<EOT>& _pop) = 0;
00160 
00164   virtual void sort_pop(eoPop<EOT>& _pop)
00165   { // start with a std::vector of indices
00166       std::vector<unsigned> indices(_pop.size());
00167 
00168     unsigned i;
00169     for (i = 0; i < _pop.size();++i)
00170     { // could use generate, but who cares
00171       indices[i] = i;
00172     }
00173 
00174     std::sort(indices.begin(), indices.end(), compare_worth(value()));
00175 
00176     eoPop<EOT>      tmp_pop;
00177     tmp_pop.resize(_pop.size());
00178     std::vector<WorthT>  tmp_worths(value().size());
00179 
00180 #ifdef _MSC_VER
00181     std::vector<EOT::Fitness> tmp_cache(_pop.size());
00182 #else
00183     std::vector<typename EOT::Fitness> tmp_cache(_pop.size());
00184 #endif
00185     for (i = 0; i < _pop.size(); ++i)
00186     {
00187       tmp_pop[i] = _pop[indices[i]];
00188       tmp_worths[i] = value()[indices[i]];
00189 
00190       tmp_cache[i] = fitness_cache[indices[i]];
00191     }
00192 
00193     std::swap(_pop, tmp_pop);
00194     std::swap(value(), tmp_worths);
00195     std::swap(fitness_cache, tmp_cache);
00196   }
00197 
00200   class compare_worth
00201   {
00202   public :
00203     compare_worth(const std::vector<WorthT>& _worths) : worths(_worths) {}
00204 
00205     bool operator()(unsigned a, unsigned b) const
00206     {
00207       return worths[b] < worths[a]; // sort in descending (!) order
00208     }
00209 
00210   private :
00211 
00212     const std::vector<WorthT>& worths;
00213   };
00214 
00215   virtual void resize(eoPop<EOT>& _pop, unsigned sz)
00216   {
00217     _pop.resize(sz);
00218     value().resize(sz);
00219     fitness_cache.resize(sz);
00220   }
00221 
00222   private :
00223   std::vector <typename EOT::Fitness> fitness_cache;
00224 };
00225 
00226 
00227 
00229 template <class EOT>
00230 class eoNoPerf2Worth : public eoPerf2Worth<EOT, typename EOT::Fitness>
00231 {
00232 public:
00233 
00234     using eoValueParam< EOT >::value;
00235 
00236     // default behaviour, just copy fitnesses
00237     void operator()(const eoPop<EOT>& _pop) {
00238         unsigned i;
00239         value().resize(_pop.size());
00240         for (i = 0; i < _pop.size(); ++i)
00241             value()[i]=_pop[i];
00242     }
00243 };
00244 
00245 
00246 
00247 #endif

Generated on Thu Apr 19 11:02:27 2007 for EO by  doxygen 1.4.7