Add usage of operators in Generation and Chromosome.
authorRafał Długołęcki <rafal@dlugolecki.net.pl>
Sun, 5 Apr 2015 15:41:21 +0000 (17:41 +0200)
committerRafał Długołęcki <rafal@dlugolecki.net.pl>
Sun, 5 Apr 2015 15:41:21 +0000 (17:41 +0200)
Optimize code. (from 10s to 6s for 1000 of generations with 200 chromosomes with 10 genes each).

src/algorithm.h
src/chromosome.h
src/crossover/crossover.h
src/fitness/fitness.h
src/fitness/wsti.h
src/generation.h
src/main.cpp
src/mutation/mutation.h
src/selection/roulette.h

index 9b2e3bea75b3bca8717c2ee6c72b22b830975708..67b7160ef0580b0407d99f0883ecca5c22a1ae87 100644 (file)
@@ -119,10 +119,10 @@ namespace genetic {
          * \attention Method is currently not in use.
          */
         void showGeneration() {
-            for (unsigned int i = 0; i < this->generation.get().size(); i++) {
+            for (unsigned int i = 0; i < this->generation.size(); i++) {
                 cout << "# " << i << ") ";
-                for (unsigned int j = 0; j < this->generation.get()[i].get().size(); j++) {
-                    cout << this->generation.get()[i].get()[j].get();
+                for (unsigned int j = 0; j < this->generation[i].size(); j++) {
+                    cout << this->generation[i][j].get();
                 }
                 cout << "\n";
             }
@@ -133,12 +133,12 @@ namespace genetic {
          */
         void showAvgFitness() {
             double avg = 0;
-            for (unsigned int i = 0; i < this->generation.get().size(); i++) {
-                _Fitness fit(this->generation.get()[i]);
+            for (unsigned int i = 0; i < this->generation.size(); i++) {
+                _Fitness fit(this->generation[i]);
                 fit.parseArguments(fitness.getArguments());
                 avg += fit.calculate();
             }
-            cout << " " << avg / this->generation.get().size();
+            cout << " " << avg / this->generation.size();
         }
 
         /**
@@ -146,8 +146,8 @@ namespace genetic {
          */
         void showBestFitness() {
             double best = -100000;
-            for (unsigned int i = 0; i < this->generation.get().size(); i++) {
-                _Fitness fit(this->generation.get()[i]);
+            for (unsigned int i = 0; i < this->generation.size(); i++) {
+                _Fitness fit(this->generation[i]);
                 fit.parseArguments(fitness.getArguments());
 
                 double tmp = fit.calculate();
index 7399ea45959607575d476c741b316b49913efb41..08d24c92c5b422290c0c3198ebf0be700b418963 100644 (file)
@@ -24,6 +24,7 @@ namespace genetic {
          */
         vector<_Gene> genes;
 
+        template<typename> friend class Chromosome;
     public:
         /**
          * Default constructor
@@ -41,7 +42,7 @@ namespace genetic {
 
         /** Copy constructor */
         Chromosome(const Chromosome& chromosome)
-            : genes(chromosome.get()) {
+            : genes(chromosome.genes) {
         }
 
         /**
@@ -51,15 +52,26 @@ namespace genetic {
          * @return Chromosome instance containing copied Genes
          */
         Chromosome& operator=(const Chromosome& chromosome) {
-            this->genes = chromosome.get();
+            this->genes = chromosome.genes;
             return *this;
         }
 
         /**
-         * Allows read-only access to Chromosome Genes
+         * Returns number of Genes in current Chromosome
+         *
+         * @return number of Genes in current Chromosome
+         */
+        unsigned int size() const {
+            return this->genes.size();
+        }
+
+        /**
+         * Returns i-th Gene in the current Chromosome
+         *
+         * @return i-th Gene in the current Chromosome
          */
-        vector<_Gene> get() const {
-            return this->genes;
+        _Gene& operator[](unsigned int i) {
+            return this->genes[i];
         }
     };
 }
index 0d9b309f7fc961f26594911f326a530727e028c5..d2eada8efb0bfe46b2d0a3edbdf6311c8bd7907b 100644 (file)
@@ -35,15 +35,15 @@ namespace genetic {
              * @return new Chromosome crossed between given two
              */
             _Chromosome do_cross(_Chromosome first, _Chromosome second, unsigned int splitPlace) {
-                const unsigned int chromosomeSize = first.get().size();
+                const unsigned int chromosomeSize = first.size();
 
 //                 cout << "        ";
 //                 for (unsigned int i = 0; i < chromosomeSize; i++) {
-//                     cout << first.get()[i].get();
+//                     cout << first[i].get();
 //                 }
 //                 cout << "\n      x ";
 //                 for (unsigned int i = 0; i < chromosomeSize; i++) {
-//                     cout << second.get()[i].get();
+//                     cout << second[i].get();
 //                 }
 //                 cout << "\n--------";
 //                 for (unsigned int i = 0; i < chromosomeSize; i++) {
@@ -58,16 +58,16 @@ namespace genetic {
                 vector<GeneType> crossedChromosome;
                 for (unsigned int i = 0; i < chromosomeSize; i++) {
                     if (i < splitPlace) {
-                        crossedChromosome.push_back(first.get()[i].get());
+                        crossedChromosome.push_back(first[i].get());
                     }
                     else {
-                        crossedChromosome.push_back(second.get()[i].get());
+                        crossedChromosome.push_back(second[i].get());
                     }
                 }
 
 //                 cout << "\n        ";
 //                 for (unsigned int i = 0; i < chromosomeSize; i++) {
-//                     cout << crossedChromosome[i].get();
+//                     cout << crossedChromosome[i];
 //                 }
 //                 cout << "\n";
 
@@ -91,14 +91,14 @@ namespace genetic {
              * @return new Generation of Chromosome's after the Crossover
              */
             Generation<_Chromosome> cross(Generation<_Chromosome> _generation) {
-                const unsigned int generationSize = _generation.get().size();
+                const unsigned int generationSize = _generation.size();
                 vector<_Chromosome> newGeneration;
 
                 for (unsigned int i = 0; i < generationSize; i++) {
                     CrossoverChanceType random = (rand() + 1 % 10000) / 10000.0;
-                    _Chromosome chromosome = _generation.get()[i];
+                    _Chromosome chromosome = _generation[i];
                     if (random < this->chance) {
-                        const unsigned int chromosomeSize = chromosome.get().size();
+                        const unsigned int chromosomeSize = chromosome.size();
                         const unsigned int splitPlace = rand() % chromosomeSize;
                         unsigned int pairedChromosome = 0;
 
@@ -109,7 +109,7 @@ namespace genetic {
                              pairedChromosome = rand() % generationSize;
                         } while(pairedChromosome == i);
 
-                        chromosome = do_cross(chromosome, _generation.get()[pairedChromosome], splitPlace);
+                        chromosome = do_cross(chromosome, _generation[pairedChromosome], splitPlace);
                     }
                     newGeneration.push_back(chromosome);
                 }
index 093490d367e1fa7add12bb9164cb62f9c1d0ee39..a9750341f32271db145a514c42b5d8691a3ae931 100644 (file)
@@ -47,7 +47,7 @@ namespace genetic {
          * Copy constructor
          */
         Fitness(_Chromosome& _chromosome)
-            : chromosome(_chromosome.get()) {
+            : chromosome(_chromosome) {
         }
 
         /**
index 3743a9ca00077143a90fb126aba02e718d3a2c46..1724936e83fb2e4121b5313ca672603480e4ab33 100644 (file)
@@ -17,14 +17,16 @@ namespace genetic {
     class WSTI : public Fitness<_Chromosome, _Value> {
     protected:
         /**
-         * Value of the begining of the Fitness function domain
+         * Value of the begining of the Fitness function domain.
+         * By default it is equal to 0.
          */
-        float span_start;
+        float span_start = 0;
 
         /**
-         * Value of the end of the Fitness function domain
+         * Value of the end of the Fitness function domain.
+         * By default it is equal to 0.
          */
-        float span_end;
+        float span_end = 0;
 
         /**
          * Calculates fenotype of the current Chromosome
@@ -32,11 +34,10 @@ namespace genetic {
         _Value fenotype() {
             int _fenotype = 0;
             int ratio = 1;
-            for (unsigned int i = 0; i < this->chromosome.get().size(); i++) {
-                _fenotype = _fenotype + this->chromosome.get()[i].get() * ratio;
+            for (unsigned int i = 0; i < this->chromosome.size(); i++) {
+                _fenotype = _fenotype + this->chromosome[i].get() * ratio;
                 ratio = ratio * 2;
             }
-//             cout << "Fenotyp: " << _fenotype << "\n";
             return _fenotype;
         }
 
@@ -44,7 +45,7 @@ namespace genetic {
          * Calculates fenotype of the current Chromosome
          */
         _Value calculateFenotype() {
-            const unsigned int power2N = 1 << this->chromosome.get().size();
+            const unsigned int power2N = 1 << this->chromosome.size();
             return span_start + (span_end - span_start) * this->fenotype() / power2N;
         }
 
index a37602897694cc6d5afabf80d59331ff74fadca5..f195d7e5d367a4d84bfe879b51154fc1c0b5739a 100644 (file)
@@ -57,6 +57,24 @@ namespace genetic {
             this->chromosomes = generation.get();
             return *this;
         }
+
+        /**
+         * Returns number of Chromosomes in current Generation
+         *
+         * @return number of Chromosomes in current Generation
+         */
+        unsigned int size() const {
+            return this->chromosomes.size();
+        }
+
+        /**
+         * Returns i-th Chromosome in the current Generation
+         *
+         * @return i-th Chromosome in the current Generation
+         */
+        _Chromosome& operator[](unsigned int i) {
+            return this->chromosomes[i];
+        }
     };
 }
 
index f2aec1380acfd130482c57cc364305fdb6da4876..80020524ee84aa74cbcfad7a2cbd2dbf7f28f8e9 100644 (file)
@@ -35,7 +35,7 @@ int main() {
     const int chromosomeSize = 10;
     const int generationSize = 200;
     const double crossoverChance = 0.75;
-    const double mutationChance = 0.01;
+    const double mutationChance = 0.1;
 
     _Fitness fitness(0.5, 2.5);
     _Generator generationGenerator(generationSize, chromosomeSize);
index 7b626ba1e63c54e07db72e0b70552191e787c046..69c2326c33fd1632205cd48018858bb3a3aef1b4 100644 (file)
@@ -49,21 +49,18 @@ namespace genetic {
              * @return new Generation of Chromosome's that passed the mutation
              */
             Generation<_Chromosome> mutate(Generation<_Chromosome> _generation) {
-                const unsigned int generationSize = _generation.get().size();
-                const unsigned int chromosomeSize = _generation.get()[0].get().size();
+                const unsigned int generationSize = _generation.size();
+                const unsigned int chromosomeSize = _generation[0].size();
                 vector<_Chromosome> newGeneration;
 
                 for (unsigned int i = 0; i < generationSize; i++) {
                     MutationChanceType random = (rand() % 10000) / 10000.0;
 
-                    _Chromosome chromosome = _generation.get()[i];
+                    _Chromosome chromosome = _generation[i];
                     if (random < this->chance) {
                         unsigned int mutatedGene = (rand() % chromosomeSize);
-                        vector<GeneType> newChromosome = chromosome.get();
 
-                        newChromosome[mutatedGene] = GeneType(!newChromosome[mutatedGene].get());
-
-                        chromosome = _Chromosome(newChromosome);
+                        chromosome[mutatedGene] = GeneType(!chromosome[mutatedGene].get());
                     }
                     newGeneration.push_back(chromosome);
                 }
index 6db71efbd38491dd7259db4f919521a963270c19..b5c1f33e1b5c55701c8d7452320f3520f84f753d 100644 (file)
@@ -109,8 +109,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;
@@ -170,7 +170,7 @@ namespace genetic {
 
                 normalizedFitness = this->normalizeFitness(
                     this->calculateGenerationFitness(this->generation),
-                    this->generation.get()[0].get().size()
+                    this->generation[0].size()
                 );
 
                 return spinRoulette(normalizedFitness);