Fixed Mutation.
authorRafał Długołęcki <rafal@dlugolecki.net.pl>
Sat, 4 Apr 2015 13:29:29 +0000 (15:29 +0200)
committerRafał Długołęcki <rafal@dlugolecki.net.pl>
Sat, 4 Apr 2015 13:29:29 +0000 (15:29 +0200)
Fixed copying of Gene.
Added Condition class which is used to check stop conditions.
Cleaned code.

src/algorithm.h
src/condition/condition.h [new file with mode: 0644]
src/gene.h
src/main.cpp
src/mutation/mutation.h

index 162fdd02afa761dc7a27e52c43944defd5c0af32..f38fff57acb3d11b055e160fc1663feae634a89e 100644 (file)
@@ -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 (file)
index 0000000..7448052
--- /dev/null
@@ -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 */
index 9786587d3d5409cf1ed0ab0a2e7996a495c600de..e4142811b3e23bd31724d9a3ae7a243af828e801 100644 (file)
@@ -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;
         }
 
index 920e3f11e354dad9b6cb55a2590505a9d04514e9..3816b435095ef27255cb76f50ab4192231da97c0 100644 (file)
@@ -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;
 }
index 20d78730b16b5af2b97696801d1879979c6c1951..69c23e7fde54c4d47334a806d61299235e71ce15 100644 (file)
@@ -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);
             }