BinaryTournamentSelect.cpp

Go to the documentation of this file.
00001 #include "BinaryTournamentSelect.h"
00002 #include "NumUtil.h"
00003 #include <iostream>
00004 #include <algorithm> // for swap
00005 #include "FatalException.h"
00006 
00007 using namespace std;
00008 namespace gplib
00009   {
00010     BinaryTournamentSelect::BinaryTournamentSelect(GeneralRNG &LocalRandom,
00011         tProbabilityFunction myPF, tDistanceFunction myDF) :
00012       distancecount(0), Random(LocalRandom), ProbabilityFunction(myPF),
00013           DistanceFunction(myDF), ReturnIndex(0)
00014       {
00015 
00016       }
00017 
00018     BinaryTournamentSelect::~BinaryTournamentSelect()
00019       {
00020         cout << "Distance Count: " << distancecount << endl;
00021       }
00022 
00023     void BinaryTournamentSelect::DoInit()
00024       {
00025         if (ProbabilityFunction().size() != DistanceFunction().size())
00026           throw FatalException(
00027               "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(
00042                 CurrentIndex)); //swap indices
00043             CurrentIndex = Random.GetNumber(popsize - i); //generate a new index
00044             swap(PopulationIndex.at(2 * popsize - i - 1), PopulationIndex.at(
00045                 popsize + CurrentIndex)); //swap indices in the secondhalf
00046           }
00047         ReturnIndex = 0;
00048       }
00049 
00050     size_t BinaryTournamentSelect::DoGetOne()
00051       {
00052         const double tolerance = 1e-5;
00053         //get two indices from the randomized PopulationIndex
00054         const int fatherindex = PopulationIndex.at(ReturnIndex);
00055         const int motherindex = PopulationIndex.at(ReturnIndex + 1);
00056         //increase index for next call
00057         ReturnIndex += 2;
00058         //compare within numerical precision
00059         const int comparison = fcmp(localprobabilities(fatherindex),
00060             localprobabilities(motherindex), tolerance);
00061         switch (comparison)
00062           {
00063         case 1:
00064           return fatherindex; //father has higher fitness
00065         case -1:
00066           return motherindex; //mother has higher fitness
00067         case 0:
00068           distancecount++; //have same fitness, decision based on crowding distance
00069           if (localdistances(fatherindex) >= localdistances(motherindex))
00070             return fatherindex;
00071           else
00072             return motherindex;
00073         default:
00074           throw FatalException(
00075               "Something went very wrong in CBinaryTournamentSelect::GetOne");
00076           }
00077       }
00078   }

Generated on Tue May 4 16:52:14 2010 for GPLIB++ by  doxygen 1.5.8