# 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