EvolvingObjects
|
00001 00025 //----------------------------------------------------------------------------- 00026 00027 #ifndef eoRanking_h 00028 #define eoRanking_h 00029 00030 #include <eoPerf2Worth.h> 00031 00039 template <class EOT> 00040 class eoRanking : public eoPerf2Worth<EOT> // false: do not cache fitness 00041 { 00042 public: 00043 00044 using eoPerf2Worth<EOT>::value; 00045 00046 /* Ctor: 00047 @param _p selective pressure (in (1,2] 00048 @param _e exponent (1 == linear) 00049 */ 00050 eoRanking(double _p=2.0, double _e=1.0): 00051 pressure(_p), exponent(_e) {} 00052 00053 /* helper function: finds index in _pop of _eo, an EOT * */ 00054 int lookfor(const EOT *_eo, const eoPop<EOT>& _pop) 00055 { 00056 typename eoPop<EOT>::const_iterator it; 00057 for (it=_pop.begin(); it<_pop.end(); it++) 00058 { 00059 if (_eo == &(*it)) 00060 return it-_pop.begin(); 00061 } 00062 throw std::runtime_error("Not found in eoLinearRanking"); 00063 } 00064 00065 /* COmputes the ranked fitness: fitnesses range in [m,M] 00066 with m=2-pressure/popSize and M=pressure/popSize. 00067 in between, the progression depstd::ends on exponent (linear if 1). 00068 */ 00069 virtual void operator()(const eoPop<EOT>& _pop) 00070 { 00071 std::vector<const EOT *> rank; 00072 _pop.sort(rank); 00073 unsigned pSize =_pop.size(); 00074 unsigned int pSizeMinusOne = pSize-1; 00075 00076 if (pSize <= 1) 00077 throw std::runtime_error("Cannot do ranking with population of size <= 1"); 00078 00079 // value() refers to the std::vector of worthes (we're in an eoParamvalue) 00080 value().resize(pSize); 00081 00082 double beta = (2-pressure)/pSize; 00083 if (exponent == 1.0) // no need for exponetial then 00084 { 00085 double alpha = (2*pressure-2)/(pSize*pSizeMinusOne); 00086 for (unsigned i=0; i<pSize; i++) 00087 { 00088 int which = lookfor(rank[i], _pop); 00089 value()[which] = alpha*(pSize-i)+beta; // worst -> 1/[P(P-1)/2] 00090 } 00091 } 00092 else // exponent != 1 00093 { 00094 double gamma = (2*pressure-2)/pSize; 00095 for (unsigned i=0; i<pSize; i++) 00096 { 00097 int which = lookfor(rank[i], _pop); 00098 // value in in [0,1] 00099 double tmp = ((double)(pSize-i))/pSize; 00100 // to the exponent, and back to [m,M] 00101 value()[which] = gamma*pow(tmp, exponent)+beta; 00102 } 00103 } 00104 } 00105 private: 00106 double pressure; // selective pressure 00107 double exponent; 00108 }; 00109 00110 00111 00112 #endif