1 #ifndef __SELECTION_ROULETTE_H
2 #define __SELECTION_ROULETTE_H
5 #include <utility> // std::pair
6 #include <algorithm> // std::sort
11 #include "chromosome.h"
12 #include "selection.h"
17 // namespace selection {
18 template < typename _Chromosome >
19 class Roulette : public Selection<_Chromosome> {
21 typedef Selection<_Chromosome> BaseType;
22 typedef typename BaseType::FitnessValueType FitnessValueType;
24 vector<FitnessValueType> calculateGenerationFitness(
25 Generation<_Chromosome> generation) {
26 vector<FitnessValueType> generationFitness;
28 for (unsigned int i = 0; i < generation.get().size(); i++) {
29 generationFitness.push_back(this->checkChromosomeFitness(generation.get()[i]));
32 return generationFitness;
34 map<FitnessValueType, _Chromosome> normalizeFitness(
35 vector<FitnessValueType> generationFitness) {
38 FitnessValueType offset;
39 map<FitnessValueType, _Chromosome> normalizedFitness;
41 min = max = generationFitness[0];
43 for (unsigned int i = 0; i < generationFitness.size(); i++) {
44 if(generationFitness[i] < min) {
45 min = generationFitness[i];
48 if(generationFitness[i] > max) {
49 max = generationFitness[i];
53 offset = (max - min) / (generationFitness.size() - 1) - min;
55 for (unsigned int i = 0; i < generationFitness.size(); i++) {
56 normalizedFitness[generationFitness[i] + offset] = this->generation.get()[i];
59 return normalizedFitness;
65 Generation<_Chromosome> spinRoulette(
66 map<FitnessValueType, _Chromosome> normalizedFitness) {
68 typedef typename std::map<FitnessValueType, _Chromosome>::iterator FitnessIterator;
70 vector<_Chromosome> selected;
71 map<FitnessValueType, _Chromosome> probabilities;
73 unsigned int size = this->generation.get().size();
76 FitnessValueType fitnessSum = 0;
78 // Calculate sum of normalized fitnesses, in order to calculate probabilities
79 for (FitnessIterator it = normalizedFitness.begin(); it != normalizedFitness.end(); it++) {
80 fitnessSum += it->first;
83 // Calculate probabilities for fitnesses
84 for (FitnessIterator it = normalizedFitness.begin(); it != normalizedFitness.end(); it++) {
85 probabilities[it->first / fitnessSum] = it->second;
89 * Spin the Roulette until we draw as many chromosomes as in the
90 * original generation.
94 random = (rand() % 10000) / 100000.0;
96 for (FitnessIterator it = probabilities.begin(); it != probabilities.end(); it++) {
97 if (it->first > random) {
99 selected.push_back(it->second);
107 return Generation<_Chromosome>(selected);
113 Generation<_Chromosome> do_draw() {
114 map<FitnessValueType, _Chromosome> normalizedFitness;
116 normalizedFitness = this->normalizeFitness(
117 this->calculateGenerationFitness(this->generation)
120 return spinRoulette(normalizedFitness);
124 Roulette(Generation<_Chromosome> _generation, genetic::Fitness<_Chromosome>& _fitness) :
125 Selection<_Chromosome>(_generation, _fitness) {
126 this->generation = _generation;
127 this->fitness = _fitness;
130 srand((unsigned)time(&t));
136 #endif /* __SELECTION_ROULETTE_H */