Fix building and installing package.
[genetic.git] / include / crossover / crossover.h
diff --git a/include/crossover/crossover.h b/include/crossover/crossover.h
new file mode 100644 (file)
index 0000000..d2eada8
--- /dev/null
@@ -0,0 +1,123 @@
+#ifndef __CROSSOVER_CROSSOVER_H
+#define __CROSSOVER_CROSSOVER_H
+
+#include "chromosome.h"
+#include "generation.h"
+
+using namespace std;
+
+namespace genetic {
+//     namespace crossover {
+        template < typename _Chromosome >
+        class Crossover {
+        public:
+            /**
+             * Type of probability of crossover chance
+             */
+            typedef double CrossoverChanceType;
+
+            /**
+             * Type representing Chromosome Gene
+             */
+            typedef typename _Chromosome::GeneType GeneType;
+        protected:
+            /**
+             * Probability of Crossover (0 = 0%, 1 = 100%)
+             */
+            CrossoverChanceType chance;
+
+            /**
+             * Crossover two Chromosome's between themself.
+             *
+             * @param first first Chromosome to Crossover
+             * @param second second Chromosome to Crossover
+             * @param splitPlace Gene number on which the Genes should be swapped
+             * @return new Chromosome crossed between given two
+             */
+            _Chromosome do_cross(_Chromosome first, _Chromosome second, unsigned int splitPlace) {
+                const unsigned int chromosomeSize = first.size();
+
+//                 cout << "        ";
+//                 for (unsigned int i = 0; i < chromosomeSize; i++) {
+//                     cout << first[i].get();
+//                 }
+//                 cout << "\n      x ";
+//                 for (unsigned int i = 0; i < chromosomeSize; i++) {
+//                     cout << second[i].get();
+//                 }
+//                 cout << "\n--------";
+//                 for (unsigned int i = 0; i < chromosomeSize; i++) {
+//                     if (i == splitPlace) {
+//                         cout << "^";
+//                     }
+//                     else {
+//                         cout << "-";
+//                     }
+//                 }
+
+                vector<GeneType> crossedChromosome;
+                for (unsigned int i = 0; i < chromosomeSize; i++) {
+                    if (i < splitPlace) {
+                        crossedChromosome.push_back(first[i].get());
+                    }
+                    else {
+                        crossedChromosome.push_back(second[i].get());
+                    }
+                }
+
+//                 cout << "\n        ";
+//                 for (unsigned int i = 0; i < chromosomeSize; i++) {
+//                     cout << crossedChromosome[i];
+//                 }
+//                 cout << "\n";
+
+                return _Chromosome(crossedChromosome);
+            }
+
+        public:
+            /**
+             * Class constructor. Initializes values.
+             *
+             * @param chance probability of Crossover (0 = 0%, 1 = 100%)
+             */
+            Crossover(CrossoverChanceType chance) :
+                chance(chance) {
+            }
+
+            /**
+             * Invokes Crossover calculations
+             *
+             * @param _generation Generation for which the crossover should be applied
+             * @return new Generation of Chromosome's after the Crossover
+             */
+            Generation<_Chromosome> cross(Generation<_Chromosome> _generation) {
+                const unsigned int generationSize = _generation.size();
+                vector<_Chromosome> newGeneration;
+
+                for (unsigned int i = 0; i < generationSize; i++) {
+                    CrossoverChanceType random = (rand() + 1 % 10000) / 10000.0;
+                    _Chromosome chromosome = _generation[i];
+                    if (random < this->chance) {
+                        const unsigned int chromosomeSize = chromosome.size();
+                        const unsigned int splitPlace = rand() % chromosomeSize;
+                        unsigned int pairedChromosome = 0;
+
+                        /**
+                         * Search for different Chromosome, and crossover them together
+                         */
+                        do {
+                             pairedChromosome = rand() % generationSize;
+                        } while(pairedChromosome == i);
+
+                        chromosome = do_cross(chromosome, _generation[pairedChromosome], splitPlace);
+                    }
+                    newGeneration.push_back(chromosome);
+                }
+
+                return Generation<_Chromosome>(newGeneration);
+            }
+        };
+//     }
+}
+
+#endif /* __CROSSOVER_CROSSOVER_H */