From: Rafał Długołęcki Date: Mon, 6 Apr 2015 14:37:52 +0000 (+0200) Subject: Added LinearRankSelection. X-Git-Url: https://git.dlugolecki.net.pl/?p=genetic.git;a=commitdiff_plain;h=5e4a04634f1d31d4c774b44184cf08d3faf4d02a Added LinearRankSelection. --- diff --git a/src/main.cpp b/src/main.cpp index 3e73d58..36dd602 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,6 +9,7 @@ #include "generator/bit.h" #include "selection/roulette.h" +#include "selection/linearRankSelection.h" #include "crossover/crossover.h" #include "mutation/mutation.h" #include "fitness/wsti.h" @@ -25,7 +26,7 @@ int main() { typedef Chromosome<_Gene> _Chromosome; typedef WSTI<_Chromosome> _Fitness; - typedef Roulette<_Chromosome> _Selection; + typedef LinearRankSelection<_Chromosome> _Selection; typedef Crossover<_Chromosome> _Crossover; typedef Mutation<_Chromosome> _Mutation; diff --git a/src/selection/linearRankSelection.h b/src/selection/linearRankSelection.h new file mode 100644 index 0000000..8a09046 --- /dev/null +++ b/src/selection/linearRankSelection.h @@ -0,0 +1,119 @@ +#ifndef __SELECTION_LINEAR_RANK_H +#define __SELECTION_LINEAR_RANK_H + +#include + +#include "chromosome.h" +#include "generation.h" +#include "fitness/fitness.h" +#include "selection/selection.h" + +using namespace std; + +namespace genetic { +// namespace selection { + /** + * Linear Rank Selection class. + * Based on the + */ + template < typename _Chromosome > + class LinearRankSelection : public Selection<_Chromosome> { + public: + /** + * Type representing Fitness function + */ + typedef Fitness<_Chromosome> GeneticFitness; + + /** + * Value type returned by the Fitness function + */ + typedef typename GeneticFitness::ValueType FitnessValueType; + protected: + typedef typename std::multimap ChromosomeMap; + typedef typename ChromosomeMap::iterator ChromosomeMapIterator; + + /** + * Calculates Ranks for the Chromosomes + * + * @return multimap containing ranked Chromosomes, where key is the + * rank value. + */ + ChromosomeMap rankChromosomes() { + const unsigned int generationSize = this->generation.size(); + FitnessValueType fitness = 0; + + ChromosomeMap generationFitness; + + for (unsigned int i = 0; i < generationSize; i++) { + fitness = this->checkChromosomeFitness(this->generation[i]); + generationFitness.insert(std::make_pair(fitness, this->generation[i])); + } + + // multimap is automatically sorted by key, so we don't need to + // sort it again + + // p(i) = (rank(i) / N*(N-1)), where rankedGeneration[i] = p(i) + ChromosomeMap rankedGeneration; + + unsigned int rank = generationSize; + double denominator = generationSize * (generationSize - 1); + + for (ChromosomeMapIterator it = generationFitness.begin(); it != generationFitness.end(); it++) { +// cout << "rank: " << rank << " denominator: " << denominator << " res: " << (rank-1)/denominator << "\n"; + rankedGeneration.insert(std::make_pair(rank--/denominator, it->second)); + } + + return rankedGeneration; + } + + /** + * Selection calculations should be done here. + * + * @return new Generation of Chromosome's that passed the Selection + */ + virtual Generation<_Chromosome> do_draw() { + ChromosomeMap probabilities = rankChromosomes(); + + unsigned int size = probabilities.size(); + unsigned int denominator = size * (size - 1); + + std::vector<_Chromosome> selected; + + /** Random value used to draw chromosome */ + FitnessValueType random = 0; + + while (size > 0) { + bool found = false; + random = (rand() % size) / (double)denominator; + + for (ChromosomeMapIterator it = probabilities.begin(); it != probabilities.end(); it++) { +// cout << "Random: " << random << " First: " << it->first << "\n"; + if (random < it->first) { + found = true; + selected.push_back(it->second); + break; + } + // When NaN occur, just get first Chromosome + else if (it->first != it->first) { + selected.push_back(probabilities.begin()->second); + found = true; + break; + } + } + + if (found) { + size--; + } + } + + return Generation<_Chromosome>(selected); + } + public: + LinearRankSelection(Generation<_Chromosome> _generation, GeneticFitness& _fitness) : + Selection<_Chromosome>(_generation, _fitness) { + } + }; +// } +} + +#endif /* __SELECTION_LINEAR_RANK_H */