EvolvingObjects
|
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