# eoLinearFitScaling.h

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