BinaryTournamentSelect.cpp

Go to the documentation of this file.
00001 #include "BinaryTournamentSelect.h"
00002 #include <gsl/gsl_math.h>
00003 #include <iostream>
00004 #include <algorithm> // for swap
00005 #include "CFatalException.h"
00006 
00007 
00008 using namespace std;
00009 BinaryTournamentSelect::BinaryTournamentSelect(GeneralRNG &LocalRandom, tProbabilityFunction myPF,tDistanceFunction myDF):
00010 distancecount(0),
00011 Random(LocalRandom),
00012 ProbabilityFunction(myPF),
00013 DistanceFunction(myDF),
00014 ReturnIndex(0)
00015 {
00016         
00017 }
00018 
00019 BinaryTournamentSelect::~BinaryTournamentSelect()
00020 {
00021         cout << "Distance Count: " << distancecount << endl;
00022 }
00023 
00024 void BinaryTournamentSelect::DoInit()
00025 {
00026         if (ProbabilityFunction().size() != DistanceFunction().size())
00027                 throw CFatalException("Probabilities and Crowding distances do not have the same size !");
00028         //Get Probabiliteis and crowding distances
00029         localprobabilities = ProbabilityFunction();
00030         localdistances = DistanceFunction();
00031         const size_t popsize = localdistances.size();
00032         PopulationIndex.assign(popsize*2,0); // we need every member index twice
00033         for (size_t i = 0; i < popsize; ++i) 
00034         {
00035                 PopulationIndex.at(i) = i;
00036                 PopulationIndex.at(i+popsize) = i;
00037         }
00038         for (size_t i = 0; i < popsize; ++i)//shuffle the indices
00039         {
00040                 int CurrentIndex = Random.GetNumber(popsize -i); //select an index for the first half
00041                 swap(PopulationIndex.at(popsize-i-1),PopulationIndex.at(CurrentIndex)); //swap indices
00042                 CurrentIndex = Random.GetNumber(popsize -i); //generate a new index
00043                 swap(PopulationIndex.at(2*popsize-i-1),PopulationIndex.at(popsize+CurrentIndex)); //swap indices in the secondhalf
00044         }
00045         ReturnIndex = 0;
00046 }
00047 
00048 size_t BinaryTournamentSelect::DoGetOne()
00049 {
00050         const double tolerance = 1e-5;
00051         //get two indices from the randomized PopulationIndex
00052         const int fatherindex = PopulationIndex.at(ReturnIndex);
00053         const int motherindex = PopulationIndex.at(ReturnIndex+1);
00054         //increase index for next call
00055         ReturnIndex += 2;
00056         //compare within numerical precision
00057         const int comparison = gsl_fcmp(localprobabilities(fatherindex), localprobabilities(motherindex), tolerance);
00058         switch (comparison)
00059         {
00060                 case 1:
00061                         return fatherindex; //father has higher fitness
00062                 case -1:
00063                         return motherindex; //mother has higher fitness
00064                 case 0:
00065                         distancecount++; //have same fitness, decision based on crowding distance
00066                         if (localdistances(fatherindex) >= localdistances(motherindex))
00067                                 return fatherindex;
00068                         else
00069                                 return motherindex;
00070                 default:
00071                         throw CFatalException("Something went very wrong in CBinaryTournamentSelect::GetOne");
00072         }        
00073 }

Generated on Fri Jul 4 15:30:20 2008 for GPLIB++ by  doxygen 1.5.5