1 #ifndef __SELECTION_LINEAR_RANK_H
2 #define __SELECTION_LINEAR_RANK_H
6 #include "chromosome.h"
7 #include "generation.h"
8 #include "fitness/fitness.h"
9 #include "selection/selection.h"
12 // namespace selection {
14 * Linear Rank Selection class.
17 template < typename _Chromosome >
18 class LinearRankSelection : public Selection<_Chromosome> {
21 * Type representing Fitness function
23 typedef Fitness<_Chromosome> GeneticFitness;
26 * Value type returned by the Fitness function
28 typedef typename GeneticFitness::ValueType FitnessValueType;
31 * Type representing mapped Chromosome by its Rank value
33 typedef typename std::multimap<FitnessValueType, _Chromosome> ChromosomeMap;
35 /** Iterator for ChromosomeMap */
36 typedef typename ChromosomeMap::iterator ChromosomeMapIterator;
39 * Calculates Ranks for the Chromosomes
41 * @return multimap containing ranked Chromosomes, where key is the
44 ChromosomeMap rankChromosomes() {
45 const unsigned int generationSize = this->generation.size();
46 FitnessValueType fitness = 0;
48 ChromosomeMap generationFitness;
50 for (unsigned int i = 0; i < generationSize; i++) {
51 fitness = this->checkChromosomeFitness(this->generation[i]);
52 generationFitness.insert(std::make_pair(fitness, this->generation[i]));
55 // multimap is automatically sorted by key, so we don't need to
58 // p(i) = (rank(i) / N*(N-1)), where rankedGeneration[i] = p(i)
59 ChromosomeMap rankedGeneration;
61 unsigned int rank = generationSize;
62 const double denominator = generationSize * (generationSize - 1);
64 for (ChromosomeMapIterator it = generationFitness.begin(); it != generationFitness.end(); it++) {
65 rankedGeneration.insert(std::make_pair(rank--/denominator, it->second));
68 return rankedGeneration;
72 * Invokes Selection calculations of the Linear Rank Selection
74 * @return new Generation of Chromosome's that passed the Selection
76 virtual Generation<_Chromosome> do_draw() {
77 ChromosomeMap probabilities = rankChromosomes();
79 unsigned int size = probabilities.size();
80 const unsigned int denominator = size * (size - 1);
82 std::vector<_Chromosome> selected;
84 /** Random value used to draw chromosome */
85 FitnessValueType random = 0;
89 random = (rand() % size) / (float)denominator;
91 for (ChromosomeMapIterator it = probabilities.begin(); it != probabilities.end(); it++) {
92 if (random < it->first) {
94 selected.push_back(it->second);
97 // When NaN occur, just get first Chromosome
98 else if (it->first != it->first) {
99 selected.push_back(probabilities.begin()->second);
110 return Generation<_Chromosome>(selected);
113 LinearRankSelection(const Generation<_Chromosome>& _generation, GeneticFitness& _fitness) :
114 Selection<_Chromosome>(_generation, _fitness) {
120 #endif /* __SELECTION_LINEAR_RANK_H */