X-Git-Url: https://git.dlugolecki.net.pl/?a=blobdiff_plain;f=src%2Fselection%2Froulette.h;h=4371df68ee55b8a075d9a13c09cbe6b3ddf19087;hb=cb1db4f6f0e4d6c65e09013c21df12b67d05d0b0;hp=a4f1fd289ad8e2b2e58c4dcbef44e00e8eb87f6f;hpb=76e7a40f8acad0645dd755a55f6321760a41e1a6;p=genetic.git diff --git a/src/selection/roulette.h b/src/selection/roulette.h index a4f1fd2..4371df6 100644 --- a/src/selection/roulette.h +++ b/src/selection/roulette.h @@ -3,7 +3,6 @@ #include #include // std::pair -#include // std::sort #include #include #include @@ -15,34 +14,71 @@ using namespace std; namespace genetic { // namespace selection { + /** + * Selection class Roulette. + * Applies Selection on given Generation using Roulette method. + */ template < typename _Chromosome > class Roulette : public Selection<_Chromosome> { public: + /** + * Parent Selection class + */ typedef Selection<_Chromosome> BaseType; + + /** + * Value type returned by the Fitness function + */ typedef typename BaseType::FitnessValueType FitnessValueType; protected: + /** + * Method used for calculating fitness of each Chromosome in + * Generation. + * + * @param generation Generation for which fitness will be calculated + * @return vector containing fitness value of each Chromosome in + * Generation. Values are set in the same order as they are in + * the Generation. + */ vector calculateGenerationFitness( Generation<_Chromosome> generation) { vector generationFitness; + unsigned int generationSize = generation.size(); - for (unsigned int i = 0; i < generation.get().size(); i++) { - generationFitness.push_back(this->checkChromosomeFitness(generation.get()[i])); + for (unsigned int i = 0; i < generationSize; i++) { + generationFitness.push_back(this->checkChromosomeFitness(generation[i])); } return generationFitness; } + + /** + * Normalizes calculated fitness values of the generation. + * + * @param generationFitness fitness values of the generation + * @param chromosomeSize number of Gene's in the Chromosome. + * + * @return multimap containing normalized Fitness as a key and its + * Chromosome as the value + */ multimap normalizeFitness( vector generationFitness, unsigned int chromosomeSize) { FitnessValueType min; FitnessValueType max; FitnessValueType offset; + + unsigned int fitnessSize = generationFitness.size(); + + /* we use multimap because it stores multiple values with the + * same key + */ multimap normalizedFitness; min = max = generationFitness[0]; offset = 0; - for (unsigned int i = 0; i < generationFitness.size(); i++) { + for (unsigned int i = 0; i < fitnessSize; i++) { if(generationFitness[i] < min) { min = generationFitness[i]; } @@ -54,8 +90,8 @@ namespace genetic { offset = (max - min) / (chromosomeSize - 1) - min; - for (unsigned int i = 0; i < generationFitness.size(); i++) { - normalizedFitness.insert(std::make_pair(generationFitness[i] + offset, this->generation.get()[i])); + for (unsigned int i = 0; i < fitnessSize; i++) { + normalizedFitness.insert(std::make_pair(generationFitness[i] + offset, this->generation[i])); } return normalizedFitness; @@ -63,6 +99,10 @@ namespace genetic { /** * Spins the Roulette + * + * @param normalizedFitness multimap containing normalized Fitness + * as a key and its Chromosome as the value + * @return new Generation of Chromosome's that passed the Selection */ Generation<_Chromosome> spinRoulette( multimap normalizedFitness) { @@ -72,8 +112,8 @@ namespace genetic { vector<_Chromosome> selected; multimap probabilities; - unsigned int size = this->generation.get().size(); - const unsigned int power2N = 1 << this->generation.get()[0].get().size(); + unsigned int size = this->generation.size(); + const unsigned int power2N = 1 << this->generation[0].size(); /** Random value used to draw chromosome */ FitnessValueType random = 0; @@ -108,7 +148,7 @@ namespace genetic { selected.push_back(it->second); break; } - // When NaN occur: + // When NaN occur, just get first Chromosome else if (it->first != it->first) { selected.push_back(probabilities.begin()->second); found = true; @@ -124,20 +164,29 @@ namespace genetic { } /** - * Draws random + * Draws new Generation using Roulette method + * + * @return new Generation of Chromosome's that passed the Selection */ Generation<_Chromosome> do_draw() { multimap normalizedFitness; normalizedFitness = this->normalizeFitness( this->calculateGenerationFitness(this->generation), - this->generation.get()[0].get().size() + this->generation[0].size() ); return spinRoulette(normalizedFitness); } public: + /** + * Class constructor. Initializes class with values. + * + * @param _generation Generation that will be checked against this + * Selection + * @param _fitness Fitness method to calculate fitness of Chromosomes + */ Roulette(Generation<_Chromosome> _generation, genetic::Fitness<_Chromosome>& _fitness) : Selection<_Chromosome>(_generation, _fitness) { this->generation = _generation;