00001 #include "ECF_base.h"
00002 #include "SelFitnessProportionalOp.h"
00003 #include "SelBestOp.h"
00004 #include "SelWorstOp.h"
00005 #include <cmath>
00006
00007
00008 bool SelFitnessProportionalOp::initialize(StateP state) {
00009 state_ = state;
00010 selPressure_ = 10;
00011 return true;
00012 }
00013
00014
00015 bool SelFitnessProportionalOp::setSelPressure(double selPressure)
00016 {
00017 if(selPressure > 0){
00018 selPressure_ = selPressure;
00019 return true;
00020 }
00021 return false;
00022 }
00023
00024
00025 IndividualP SelFitnessProportionalOp::select(const std::vector<IndividualP>& pool)
00026 {
00027 if(pool.empty())
00028 return IndividualP();
00029
00030 SelBestOp best_;
00031 SelWorstOp worst_;
00032 IndividualP best = best_.select(pool);
00033 IndividualP worst = worst_.select(pool);
00034 double bestVal = best->fitness->getValue();
00035 double worstVal = worst->fitness->getValue();
00036 std::vector<double> howFit(pool.size(), 0.);
00037
00038
00039 if(fabs(bestVal - worstVal) < 0.000001)
00040 bestVal = worstVal + 1;
00041
00042 howFit[0] = 1 + (selPressure_ - 1) * (pool[0]->fitness->getValue() - worstVal)/(bestVal - worstVal);
00043 for(uint i = 1; i<pool.size(); i++) {
00044 howFit[i] = 1 + (selPressure_ - 1) * (pool[i]->fitness->getValue() - worstVal)/(bestVal - worstVal);
00045 howFit[i] += howFit[i-1];
00046 }
00047
00048 double randVal = state_->getRandomizer()->getRandomDouble() * howFit[howFit.size() - 1];
00049 uint chosen = 0;
00050 while(howFit[chosen] < randVal)
00051 chosen++;
00052
00053 return pool[chosen];
00054 }
00055
00056
00057 std::vector<IndividualP> SelFitnessProportionalOp::selectMany(const std::vector<IndividualP>& pool, uint repeats)
00058 {
00059 if(pool.empty())
00060 return pool;
00061
00062 SelBestOp best_;
00063 SelWorstOp worst_;
00064 IndividualP best = best_.select(pool);
00065 IndividualP worst = worst_.select(pool);
00066 double bestVal = best->fitness->getValue();
00067 double worstVal = worst->fitness->getValue();
00068 std::vector<double> howFit(pool.size(), 0.);
00069 std::vector<IndividualP> selected;
00070
00071
00072 if(fabs(bestVal - worstVal) < 0.000001)
00073 bestVal = worstVal + 1;
00074
00075 howFit[0] = 1 + (selPressure_ - 1) * (pool[0]->fitness->getValue() - worstVal)/(bestVal - worstVal);
00076 for(uint i = 1; i<pool.size(); i++) {
00077 howFit[i] = 1 + (selPressure_ - 1) * (pool[i]->fitness->getValue() - worstVal)/(bestVal - worstVal);
00078 howFit[i] += howFit[i-1];
00079 }
00080
00081 for(uint i = 0; i < repeats; i++) {
00082 double randVal = state_->getRandomizer()->getRandomDouble() * howFit[howFit.size() - 1];
00083 uint chosen = 0, begin = 0, end = (uint) howFit.size() - 1;
00084 while((begin + 1) < end) {
00085 chosen = (begin + end) / 2;
00086 if(howFit[chosen] > randVal)
00087 end = chosen;
00088 else
00089 begin = chosen;
00090 }
00091 if(howFit[begin] >= randVal)
00092 chosen = begin;
00093 else
00094 chosen = end;
00095
00096
00097
00098 selected.push_back(pool[chosen]);
00099 }
00100
00101 return selected;
00102 }