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 {
00058 std::vector<unsigned> indices(_pop.size());
00059
00060 unsigned i;
00061 for (i = 0; i < _pop.size();++i)
00062 {
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];
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 {
00142 return;
00143 }
00144 }
00145 else
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
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 {
00166 std::vector<unsigned> indices(_pop.size());
00167
00168 unsigned i;
00169 for (i = 0; i < _pop.size();++i)
00170 {
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];
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
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