Apply small optimizations.
[genetic.git] / src / selection / roulette.h
index a4f1fd289ad8e2b2e58c4dcbef44e00e8eb87f6f..4371df68ee55b8a075d9a13c09cbe6b3ddf19087 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <vector>
 #include <utility>      // std::pair
-#include <algorithm>    // std::sort
 #include <map>
 #include <cstdlib>
 #include <iostream>
@@ -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<FitnessValueType> calculateGenerationFitness(
                 Generation<_Chromosome> generation) {
                 vector<FitnessValueType> 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<FitnessValueType, _Chromosome> normalizeFitness(
                 vector<FitnessValueType> 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<FitnessValueType, _Chromosome> 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<FitnessValueType, _Chromosome> normalizedFitness) {
@@ -72,8 +112,8 @@ namespace genetic {
                 vector<_Chromosome> selected;
                 multimap<FitnessValueType, _Chromosome> 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<FitnessValueType, _Chromosome> 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;