EvolvingObjects
|
00001 00025 //----------------------------------------------------------------------------- 00026 00027 #ifndef eoLinearFitScaling_h 00028 #define eoLinearFitScaling_h 00029 00030 #include <eoSelectFromWorth.h> 00031 #include <eoPerf2Worth.h> 00032 00044 template <class EOT> 00045 class eoLinearFitScaling : public eoPerf2Worth<EOT> // false: do not cache fitness 00046 { 00047 public: 00048 00049 using eoPerf2Worth<EOT>::value; 00050 00051 /* Ctor: 00052 @param _p selective pressure (in (1,2]) 00053 @param _e exponent (1 == linear) 00054 */ 00055 eoLinearFitScaling(double _p=2.0) 00056 : pressure(_p) {} 00057 00058 /* COmputes the ranked fitness: fitnesses range in [m,M] 00059 with m=2-pressure/popSize and M=pressure/popSize. 00060 in between, the progression depends on exponent (linear if 1). 00061 */ 00062 virtual void operator()(const eoPop<EOT>& _pop) { 00063 unsigned pSize =_pop.size(); 00064 // value() refers to the vector of worthes (we're in an eoParamvalue) 00065 value().resize(pSize); 00066 00067 // best and worse fitnesses 00068 double bestFitness = static_cast<double> (_pop.best_element().fitness()); 00069 // double worstFitness = static_cast<double> (_pop.worse_element().fitness()); 00070 00071 // average fitness 00072 double sum=0.0; 00073 unsigned i; 00074 for (i=0; i<pSize; i++) 00075 sum += static_cast<double>(_pop[i].fitness()); 00076 double averageFitness = sum/pSize; 00077 00078 // the coefficients for linear scaling 00079 double denom = pSize*(bestFitness - averageFitness); 00080 double alpha = (pressure-1)/denom; 00081 double beta = (bestFitness - pressure*averageFitness)/denom; 00082 00083 for (i=0; i<pSize; i++) { // truncate to 0 00084 value()[i] = std::max(alpha*_pop[i].fitness()+beta, 0.0); 00085 } 00086 } 00087 00088 private: 00089 double pressure; // selective pressure 00090 }; 00091 00092 00093 00094 #endif