EvolvingObjects
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 
00045 template <class EOT, class WorthT = double>
00046 class eoPerf2Worth : public eoUF<const eoPop<EOT>&, void>, public eoValueParam<std::vector<WorthT> >
00047 {
00048 public:
00049 
00050     using eoValueParam<std::vector<WorthT> >::value;
00051 
00053     eoPerf2Worth(std::string _description = "Worths")
00054         : eoValueParam<std::vector<WorthT> >(std::vector<WorthT>(0), _description)
00055         {}
00056 
00059   virtual void sort_pop(eoPop<EOT>& _pop)
00060   { // start with a std::vector of indices
00061       std::vector<unsigned> indices(_pop.size());
00062 
00063     unsigned i;
00064     for (i = 0; i < _pop.size();++i)
00065     { // could use generate, but who cares
00066       indices[i] = i;
00067     }
00068 
00069     std::sort(indices.begin(), indices.end(), compare_worth(value()));
00070 
00071     eoPop<EOT>      tmp_pop;
00072     tmp_pop.resize(_pop.size());
00073     std::vector<WorthT>  tmp_worths(value().size());
00074 
00075     for (i = 0; i < _pop.size(); ++i)
00076     {
00077       tmp_pop[i] = _pop[indices[i]];
00078       tmp_worths[i] = value()[indices[i]];
00079     }
00080 
00081     std::swap(_pop, tmp_pop);
00082     std::swap(value(), tmp_worths);
00083   }
00084 
00086     class compare_worth
00087     {
00088     public:
00089 
00090         compare_worth(const std::vector<WorthT>& _worths) : worths(_worths) {}
00091 
00092         bool operator()(unsigned a, unsigned b) const {
00093             return worths[b] < worths[a]; // sort in descending (!) order
00094         }
00095 
00096     private:
00097 
00098         const std::vector<WorthT>& worths;
00099     };
00100 
00101 
00102 
00103     virtual void resize(eoPop<EOT>& _pop, unsigned sz) {
00104         _pop.resize(sz);
00105         value().resize(sz);
00106     };
00107 
00108 };
00109 
00115 template <class EOT, class WorthT = typename EOT::Fitness>
00116 class eoPerf2WorthCached : public eoPerf2Worth<EOT, WorthT>
00117 {
00118 public:
00119 
00120     using eoPerf2Worth<EOT, WorthT>::value;
00121 
00122     eoPerf2WorthCached(std::string _description = "Worths") : eoPerf2Worth<EOT, WorthT>(_description) {}
00123 
00124 
00130   void operator()(const eoPop<EOT>& _pop)
00131   {
00132     unsigned i;
00133       if (fitness_cache.size() == _pop.size())
00134       {
00135         bool in_sync = true;
00136         for (i = 0; i < _pop.size(); ++i)
00137         {
00138           if (fitness_cache[i] != _pop[i].fitness())
00139           {
00140             in_sync = false;
00141             fitness_cache[i] = _pop[i].fitness();
00142           }
00143         }
00144 
00145         if (in_sync)
00146         { // worths are up to date
00147           return;
00148         }
00149       }
00150       else // just cache the fitness
00151       {
00152         fitness_cache.resize(_pop.size());
00153         for (i = 0; i < _pop.size(); ++i)
00154         {
00155           fitness_cache[i] = _pop[i].fitness();
00156         }
00157       }
00158 
00159     // call derived implementation of perf2worth mapping
00160     calculate_worths(_pop);
00161   }
00162 
00164   virtual void calculate_worths(const eoPop<EOT>& _pop) = 0;
00165 
00169   virtual void sort_pop(eoPop<EOT>& _pop)
00170   { // start with a std::vector of indices
00171       std::vector<unsigned> indices(_pop.size());
00172 
00173     unsigned i;
00174     for (i = 0; i < _pop.size();++i)
00175     { // could use generate, but who cares
00176       indices[i] = i;
00177     }
00178 
00179     std::sort(indices.begin(), indices.end(), compare_worth(value()));
00180 
00181     eoPop<EOT>      tmp_pop;
00182     tmp_pop.resize(_pop.size());
00183     std::vector<WorthT>  tmp_worths(value().size());
00184 
00185 #ifdef _MSC_VER
00186     std::vector<EOT::Fitness> tmp_cache(_pop.size());
00187 #else
00188     std::vector<typename EOT::Fitness> tmp_cache(_pop.size());
00189 #endif
00190     for (i = 0; i < _pop.size(); ++i)
00191     {
00192       tmp_pop[i] = _pop[indices[i]];
00193       tmp_worths[i] = value()[indices[i]];
00194 
00195       tmp_cache[i] = fitness_cache[indices[i]];
00196     }
00197 
00198     std::swap(_pop, tmp_pop);
00199     std::swap(value(), tmp_worths);
00200     std::swap(fitness_cache, tmp_cache);
00201   }
00202 
00205   class compare_worth
00206   {
00207   public :
00208     compare_worth(const std::vector<WorthT>& _worths) : worths(_worths) {}
00209 
00210     bool operator()(unsigned a, unsigned b) const
00211     {
00212       return worths[b] < worths[a]; // sort in descending (!) order
00213     }
00214 
00215   private :
00216 
00217     const std::vector<WorthT>& worths;
00218   };
00219 
00220   virtual void resize(eoPop<EOT>& _pop, unsigned sz)
00221   {
00222     _pop.resize(sz);
00223     value().resize(sz);
00224     fitness_cache.resize(sz);
00225   }
00226 
00227   private :
00228   std::vector <typename EOT::Fitness> fitness_cache;
00229 };
00230 
00231 
00232 
00237 template <class EOT>
00238 class eoNoPerf2Worth : public eoPerf2Worth<EOT, typename EOT::Fitness>
00239 {
00240 public:
00241 
00242     using eoValueParam< EOT >::value;
00243 
00244     // default behaviour, just copy fitnesses
00245     void operator()(const eoPop<EOT>& _pop) {
00246         unsigned i;
00247         value().resize(_pop.size());
00248         for (i = 0; i < _pop.size(); ++i)
00249             value()[i]=_pop[i];
00250     }
00251 };
00252 
00253 
00254 
00255 #endif
 All Classes Namespaces Files Functions Variables Typedefs Friends