From 7a36adcd1e7cbf19e0823e040f1531b412351cae Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafa=C5=82=20D=C5=82ugo=C5=82=C4=99cki?= 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 newChromosome = chromosome.get(); + + newChromosome[mutatedGene] = GeneType(!newChromosome[mutatedGene].get()); + + chromosome = _Chromosome(newChromosome); } + newGeneration.push_back(chromosome); } return Generation<_Chromosome>(newGeneration); } -- 2.30.2