Added classes: Algorithm, Crossover, Mutation. Fixed Roulette.
[genetic.git] / src / algorithm.h
1 #ifndef __ALGORITHM_H
2 #define __ALGORITHM_H
3
4 #include <iostream>
5
6 #include "chromosome.h"
7 #include "generation.h"
8 #include "fitness/fitness.h"
9 #include "generator/generation.h"
10 #include "selection/selection.h"
11 #include "crossover/crossover.h"
12 #include "mutation/mutation.h"
13
14 using namespace std;
15
16 namespace genetic {
17     /**
18      * Genetic Algorithm itself
19      */
20     template < typename _Chromosome, typename _Selection, typename _Crossover, typename _Mutation >
21     class Algorithm {
22     public:
23         typedef typename _Selection::FitnessValueType FitnessValueType;
24     protected:
25         /**
26          * Generator which draws initial population
27          */
28         generator::Generation<_Chromosome>& generator;
29
30         /**
31          * Fitness function used in selection
32          */
33         Fitness<_Chromosome, FitnessValueType>& fitness;
34
35         /**
36          * Crossover function
37          */
38         _Crossover crossover;
39
40         /**
41          * Mutation function
42          */
43         _Mutation mutation;
44
45         /**
46          * Current population
47          */
48         Generation<_Chromosome> generation;
49
50         const int numberOfGenerations = 100;
51     public:
52         Algorithm(
53             generator::Generation<_Chromosome>& _generator,
54             Fitness<_Chromosome, FitnessValueType>& _fitness,
55             double crossoverChance,
56             double mutationChance) :
57                 generator(_generator),
58                 fitness(_fitness),
59                 crossover(crossoverChance),
60                 mutation(mutationChance) {
61
62             this->generation = this->generator.breed();
63         }
64
65         void searchForResult() {
66             cout << "generation avg best" << endl;
67             for(int i = 0; i < this->numberOfGenerations; i++) {
68                 cout << i;
69                 _Selection selection(this->generation, fitness);
70 //                 cout << "[+] Algorithm::Selection.draw()\n";
71                 this->generation = selection.draw();
72 //                 cout << "[+] Crossover\n";
73                 this->generation = crossover.cross(this->generation);
74 //                 cout << "[+] Mutate\n";
75                 this->generation = mutation.mutate(this->generation);
76
77 //                 cout << "New Generation:\n";
78 //                 this->showGeneration();
79                 this->showAvgFitness();
80                 this->showBestFitness();
81             }
82         }
83
84         void showGeneration() {
85             for (unsigned int i = 0; i < this->generation.get().size(); i++) {
86                 cout << "# " << i << ") ";
87                 for (unsigned int j = 0; j < this->generation.get()[i].get().size(); j++) {
88                     cout << this->generation.get()[i].get()[j].get();
89                 }
90                 cout << "\n";
91             }
92         }
93         
94         void showAvgFitness() {
95             double avg = 0;
96 //             cout << "Fitness:\n";
97             for (unsigned int i = 0; i < this->generation.get().size(); i++) {
98 //                 cout << "# " << i << ") ";
99                 WSTI<_Chromosome, FitnessValueType> fit(this->generation.get()[i], 0.5, 2.5);
100 //                 cout << fit.calculate() << "\n";
101                 avg += fit.calculate();
102             }
103             cout << " " << avg / this->generation.get().size();
104         }
105         
106         void showBestFitness() {
107             double best = -100000;
108             for (unsigned int i = 0; i < this->generation.get().size(); i++) {
109 //                 cout << "# " << i << ") ";
110                 WSTI<_Chromosome, FitnessValueType> fit(this->generation.get()[i], 0.5, 2.5);
111 //                 cout << fit.calculate() << "\n";
112                 double tmp = fit.calculate();
113                 if (tmp > best) {
114                     best = tmp;
115                 }
116             }
117             cout << " " << best << endl;
118         }
119     };
120 }
121
122 #endif /* __ALGORITHM_H */