+#ifndef __ALGORITHM_H
+#define __ALGORITHM_H
+
+#include <iostream>
+
+#include "chromosome.h"
+#include "generation.h"
+#include "fitness/fitness.h"
+#include "generator/generation.h"
+#include "selection/selection.h"
+#include "crossover/crossover.h"
+#include "mutation/mutation.h"
+
+using namespace std;
+
+namespace genetic {
+ /**
+ * Genetic Algorithm itself
+ */
+ template < typename _Chromosome, typename _Selection, typename _Crossover, typename _Mutation >
+ class Algorithm {
+ public:
+ typedef typename _Selection::FitnessValueType FitnessValueType;
+ protected:
+ /**
+ * Generator which draws initial population
+ */
+ generator::Generation<_Chromosome>& generator;
+
+ /**
+ * Fitness function used in selection
+ */
+ Fitness<_Chromosome, FitnessValueType>& fitness;
+
+ /**
+ * Crossover function
+ */
+ _Crossover crossover;
+
+ /**
+ * Mutation function
+ */
+ _Mutation mutation;
+
+ /**
+ * Current population
+ */
+ Generation<_Chromosome> generation;
+
+ const int numberOfGenerations = 100;
+ public:
+ Algorithm(
+ generator::Generation<_Chromosome>& _generator,
+ Fitness<_Chromosome, FitnessValueType>& _fitness,
+ double crossoverChance,
+ double mutationChance) :
+ generator(_generator),
+ fitness(_fitness),
+ crossover(crossoverChance),
+ mutation(mutationChance) {
+
+ this->generation = this->generator.breed();
+ }
+
+ void searchForResult() {
+ cout << "generation avg best" << endl;
+ for(int i = 0; i < this->numberOfGenerations; i++) {
+ cout << i;
+ _Selection selection(this->generation, fitness);
+// cout << "[+] Algorithm::Selection.draw()\n";
+ this->generation = selection.draw();
+// cout << "[+] Crossover\n";
+ this->generation = crossover.cross(this->generation);
+// cout << "[+] Mutate\n";
+ this->generation = mutation.mutate(this->generation);
+
+// cout << "New Generation:\n";
+// this->showGeneration();
+ this->showAvgFitness();
+ this->showBestFitness();
+ }
+ }
+
+ void showGeneration() {
+ for (unsigned int i = 0; i < this->generation.get().size(); i++) {
+ cout << "# " << i << ") ";
+ for (unsigned int j = 0; j < this->generation.get()[i].get().size(); j++) {
+ cout << this->generation.get()[i].get()[j].get();
+ }
+ cout << "\n";
+ }
+ }
+
+ void showAvgFitness() {
+ double avg = 0;
+// cout << "Fitness:\n";
+ for (unsigned int i = 0; i < this->generation.get().size(); i++) {
+// cout << "# " << i << ") ";
+ WSTI<_Chromosome, FitnessValueType> fit(this->generation.get()[i], 0.5, 2.5);
+// cout << fit.calculate() << "\n";
+ avg += fit.calculate();
+ }
+ cout << " " << avg / this->generation.get().size();
+ }
+
+ void showBestFitness() {
+ double best = -100000;
+ for (unsigned int i = 0; i < this->generation.get().size(); i++) {
+// cout << "# " << i << ") ";
+ WSTI<_Chromosome, FitnessValueType> fit(this->generation.get()[i], 0.5, 2.5);
+// cout << fit.calculate() << "\n";
+ double tmp = fit.calculate();
+ if (tmp > best) {
+ best = tmp;
+ }
+ }
+ cout << " " << best << endl;
+ }
+ };
+}
+
+#endif /* __ALGORITHM_H */