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