From 7a36adcd1e7cbf19e0823e040f1531b412351cae Mon Sep 17 00:00:00 2001
From: =?utf8?q?Rafa=C5=82=20D=C5=82ugo=C5=82=C4=99cki?=
 <rafal@dlugolecki.net.pl>
Date: Sat, 4 Apr 2015 15:29:29 +0200
Subject: [PATCH] Fixed Mutation. Fixed copying of Gene. Added Condition class
 which is used to check stop conditions. Cleaned code.

---
 src/algorithm.h           | 23 ++++++++++++--------
 src/condition/condition.h | 46 +++++++++++++++++++++++++++++++++++++++
 src/gene.h                |  3 ++-
 src/main.cpp              | 10 +++++----
 src/mutation/mutation.h   | 14 +++++++-----
 5 files changed, 77 insertions(+), 19 deletions(-)
 create mode 100644 src/condition/condition.h

diff --git a/src/algorithm.h b/src/algorithm.h
index 162fdd0..f38fff5 100644
--- a/src/algorithm.h
+++ b/src/algorithm.h
@@ -11,6 +11,8 @@
 #include "crossover/crossover.h"
 #include "mutation/mutation.h"
 
+#include "condition/condition.h"
+
 using namespace std;
 
 namespace genetic {
@@ -47,7 +49,12 @@ namespace genetic {
          */
         Generation<_Chromosome> generation;
 
-        const int numberOfGenerations = 100;
+        void do_search() {
+            _Selection selection(this->generation, fitness);
+            this->generation = selection.draw();
+            this->generation = crossover.cross(this->generation);
+            this->generation = mutation.mutate(this->generation);
+        }
     public:
         Algorithm(
             generator::Generation<_Chromosome>& _generator,
@@ -62,20 +69,18 @@ namespace genetic {
             this->generation = this->generator.breed();
         }
 
-        void searchForResult() {
-            cout << "generation avg best" << endl;
-            for(int i = 0; i < this->numberOfGenerations; i++) {
+        void searchForResult(Condition<_Chromosome>& condition) {
+            unsigned int i = 0;
+            cout << "generation avg best\n";
+            do {
                 cout << i;
-                _Selection selection(this->generation, fitness);
-                this->generation = selection.draw();
-                this->generation = crossover.cross(this->generation);
-                this->generation = mutation.mutate(this->generation);
+                do_search();
 
 //                 cout << "New Generation:\n";
 //                 this->showGeneration();
                 this->showAvgFitness();
                 this->showBestFitness();
-            }
+            } while(condition.check(this->generation) && ++i);
         }
 
         void showGeneration() {
diff --git a/src/condition/condition.h b/src/condition/condition.h
new file mode 100644
index 0000000..7448052
--- /dev/null
+++ b/src/condition/condition.h
@@ -0,0 +1,46 @@
+#ifndef __ALGORITHM_CONDITION_H
+#define __ALGORITHM_CONDITION_H
+
+#include "chromosome.h"
+#include "generation.h"
+
+using namespace std;
+
+namespace genetic {
+    /**
+     * Condition class.
+     * It is used for checking if algorithm should stop.
+     *
+     * By default stops algorithm after 1000 of generations.
+     */
+    template < typename _Chromosome>
+    class Condition {
+    public:
+    protected:
+        unsigned int currentGeneration = 0;
+    private:
+        const unsigned int maxNumberOfGenerations = 1000;
+    public:
+        Condition() { }
+
+        /**
+         * Checks if current generation passes stop condition.
+         * If condition is satisfied, we can check another generation.
+         *
+         * @param generation current generation to check
+         *
+         * @return true if condition is satisfied and another generation can checked;
+         *      false if condition is not satisfied and algorithm should stop.
+         */
+        virtual bool check(Generation<_Chromosome> generation) {
+            if (currentGeneration >= maxNumberOfGenerations) {
+                return false;
+            }
+            currentGeneration++;
+
+            return true;
+        }
+    };
+}
+
+#endif /* __ALGORITHM_CONDITION_H */
diff --git a/src/gene.h b/src/gene.h
index 9786587..e414281 100644
--- a/src/gene.h
+++ b/src/gene.h
@@ -20,7 +20,8 @@ namespace genetic {
         /** Copy constructor */
         Gene(const Gene& gene) : value(gene.get()) {}
 
-        Gene& operator=(const Gene&){
+        Gene& operator=(const Gene& gene) {
+            this->value = gene.get();
             return *this;
         }
 
diff --git a/src/main.cpp b/src/main.cpp
index 920e3f1..3816b43 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -12,6 +12,7 @@
 #include "fitness/wsti.h"
 
 #include "algorithm.h"
+#include "condition/condition.h"
 
 using namespace std;
 using namespace genetic;
@@ -27,19 +28,20 @@ int main() {
 
     typedef generator::Generation<_Chromosome> _Generator;
     typedef Algorithm<_Chromosome, _Selection, _Crossover, _Mutation> _Algorithm;
+    typedef Condition<_Chromosome> _Condition;
 
-    const int chromosomeSize = 11;
-    const int generationSize = 30;
+    const int chromosomeSize = 10;
+    const int generationSize = 200;
     const double crossoverChance = 0.75;
     const double mutationChance = 0.01;
-//     const int numberOfGenerations = 100;
 
     _Fitness fitness(0.5, 2.5);
     _Generator generationGenerator(generationSize, chromosomeSize);
 
     _Algorithm algorithm(generationGenerator, fitness, crossoverChance, mutationChance);
+    _Condition condition;
 
-    algorithm.searchForResult();
+    algorithm.searchForResult(condition);
 
     return 0;
 }
diff --git a/src/mutation/mutation.h b/src/mutation/mutation.h
index 20d7873..69c23e7 100644
--- a/src/mutation/mutation.h
+++ b/src/mutation/mutation.h
@@ -14,6 +14,7 @@ namespace genetic {
         class Mutation {
         public:
             typedef double MutationChanceType;
+            typedef typename _Chromosome::GeneType GeneType;
         protected:
             MutationChanceType chance;
 
@@ -29,14 +30,17 @@ namespace genetic {
 
                 for (unsigned int i = 0; i < generationSize; i++) {
                     MutationChanceType random = (rand() % 10000) / 10000.0;
-//                     cout << " Mutation chance: " << chance << ", random: " << random << "\n";
-                    newGeneration.push_back(_generation.get()[i]);
 
+                    _Chromosome chromosome = _generation.get()[i];
                     if (random < this->chance) {
-//                         cout << " > Mutated!\n";
-                        unsigned int which = (rand() % chromosomeSize);
-                        newGeneration[i].get()[which] = !newGeneration[i].get()[which].get();
+                        unsigned int mutatedGene = (rand() % chromosomeSize);
+                        vector<GeneType> newChromosome = chromosome.get();
+
+                        newChromosome[mutatedGene] = GeneType(!newChromosome[mutatedGene].get());
+
+                        chromosome = _Chromosome(newChromosome);
                     }
+                    newGeneration.push_back(chromosome);
                 }
                 return Generation<_Chromosome>(newGeneration);
             }
-- 
2.30.2