From af69896de7f61e773e62dfdcfa75f7788dd0dd37 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafa=C5=82=20D=C5=82ugo=C5=82=C4=99cki?= Date: Sun, 5 Apr 2015 10:25:39 +0200 Subject: [PATCH] Made Algorithm functions more generic. --- src/algorithm.h | 16 +++++++------- src/fitness/fitness.h | 19 ++++++++++++++++ src/fitness/wsti.h | 50 +++++++++++++++++++++++++++++++++++++++++-- src/main.cpp | 4 +++- 4 files changed, 78 insertions(+), 11 deletions(-) diff --git a/src/algorithm.h b/src/algorithm.h index 894f488..9b2e3be 100644 --- a/src/algorithm.h +++ b/src/algorithm.h @@ -19,7 +19,7 @@ namespace genetic { /** * Genetic Algorithm itself */ - template < typename _Chromosome, typename _Selection, typename _Crossover, typename _Mutation > + template < typename _Chromosome, typename _Selection, typename _Crossover, typename _Mutation, typename _Fitness = Fitness<_Chromosome, typename _Selection::FitnessValueType > > class Algorithm { public: /** @@ -38,7 +38,7 @@ namespace genetic { * It is a reference, because Fitness is purely virtual class and we * can't have instance of it. It must be one of derived classes. */ - Fitness<_Chromosome, FitnessValueType>& fitness; + _Fitness& fitness; /** * Crossover function @@ -79,7 +79,7 @@ namespace genetic { */ Algorithm( generator::Generation<_Chromosome>& _generator, - Fitness<_Chromosome, FitnessValueType>& _fitness, + _Fitness& _fitness, double crossoverChance, double mutationChance) : generator(_generator), @@ -130,12 +130,12 @@ namespace genetic { /** * Displays average fitness value of the entire generation. - * @todo make it more generic */ void showAvgFitness() { double avg = 0; for (unsigned int i = 0; i < this->generation.get().size(); i++) { - WSTI<_Chromosome, FitnessValueType> fit(this->generation.get()[i], 0.5, 2.5); + _Fitness fit(this->generation.get()[i]); + fit.parseArguments(fitness.getArguments()); avg += fit.calculate(); } cout << " " << avg / this->generation.get().size(); @@ -143,13 +143,13 @@ namespace genetic { /** * Displays best fitness value of the entire generation. - * @todo make it more generic, currently has hardcoded WSTI Fitness - * class, due its additional arguments */ void showBestFitness() { double best = -100000; for (unsigned int i = 0; i < this->generation.get().size(); i++) { - WSTI<_Chromosome, FitnessValueType> fit(this->generation.get()[i], 0.5, 2.5); + _Fitness fit(this->generation.get()[i]); + fit.parseArguments(fitness.getArguments()); + double tmp = fit.calculate(); if (tmp > best) { best = tmp; diff --git a/src/fitness/fitness.h b/src/fitness/fitness.h index 66263f1..093490d 100644 --- a/src/fitness/fitness.h +++ b/src/fitness/fitness.h @@ -1,6 +1,9 @@ #ifndef __FITNESS_FITNESS_H #define __FITNESS_FITNESS_H +#include +#include + #include "chromosome.h" namespace genetic { @@ -55,6 +58,22 @@ namespace genetic { _Value calculate() { return this->do_calculate(); } + + /** + * Method used to pass additional arguments needed by the function to + * run correctly. + */ + virtual void parseArguments(std::map) { } + + /** + * Method used to get additional arguments needed by the function to + * run correctly + * + * @return map containing additional arguments, empty if do not use any + */ + virtual std::map getArguments() { + return std::map(); + } }; } diff --git a/src/fitness/wsti.h b/src/fitness/wsti.h index d99dd18..3743a9c 100644 --- a/src/fitness/wsti.h +++ b/src/fitness/wsti.h @@ -57,7 +57,16 @@ namespace genetic { } public: /** - * Class constructor. Initializes class with requied values. + * Class constructor. Initializes class with required values. + * + * @param _chromosome Chromosome, for which value will be calculated + */ + WSTI(_Chromosome& _chromosome) + : Fitness<_Chromosome>(_chromosome) { + } + + /** + * Class constructor. Initializes class with required values. * * @param start begining of the Fitness function domain * @param end end of the Fitness function domain @@ -67,7 +76,7 @@ namespace genetic { } /** - * Class constructor. Initializes class with requied values. + * Class constructor. Initializes class with required values. * * @param _chromosome Chromosome, for which value will be calculated * @param start begining of the Fitness function domain @@ -76,6 +85,43 @@ namespace genetic { WSTI(_Chromosome& _chromosome, float start, float end) : Fitness<_Chromosome>(_chromosome), span_start(start), span_end(end) { } + + /** + * Method used to pass additional arguments needed by the function to + * run correctly. + * Required map keys are: + * - _span_start_ - with value equal to begining of the Fitness function domain + * - _span_end_ - with value equal to end of the Fitness function domain + * Their values should be floats. + * + * @param args map containing span_start and span_end as a keys and + * their values (_double_) passed as strings + */ + virtual void parseArguments(std::map args) { + std::map::iterator it; + for (it = args.begin(); it != args.end(); it++) { + if (it->first == "span_start") { + this->span_start = std::stod(it->second); + } + else if (it->first == "span_end") { + this->span_end = std::stod(it->second); + } + } + } + + /** + * Method used to get additional arguments needed by the function to + * run correctly. + * + * @return map containing span_start and span_end as a map keys, with + * their values passed as string + */ + std::map getArguments() { + std::map fit_args; + fit_args.insert(std::pair("span_start", std::to_string(span_start))); + fit_args.insert(std::pair("span_end", std::to_string(span_end))); + return fit_args; + } }; } diff --git a/src/main.cpp b/src/main.cpp index 3816b43..f2aec13 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include "gene.h" #include "chromosome.h" @@ -27,7 +29,7 @@ int main() { typedef Mutation<_Chromosome> _Mutation; typedef generator::Generation<_Chromosome> _Generator; - typedef Algorithm<_Chromosome, _Selection, _Crossover, _Mutation> _Algorithm; + typedef Algorithm<_Chromosome, _Selection, _Crossover, _Mutation, _Fitness> _Algorithm; typedef Condition<_Chromosome> _Condition; const int chromosomeSize = 10; -- 2.30.2