Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef DNA_HPP
- #define DNA_HPP
- #include <iostream>
- #include <cstdlib>
- #include <ctime>
- #include <cstring>
- #include <random>
- #include <memory>
- std::string sampleSpace("ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz");
- class DNA {
- private:
- int length;
- std::vector<char> genes;
- float fitness;
- bool isDone;
- // Random engine
- static std::mt19937 random;
- public:
- DNA() {
- length = 0;
- genes.resize(length);
- fitness = 0;
- isDone = false;
- }
- //----------------------------------------------------------------------
- void initialize(int len) {
- this -> length = len;
- this -> genes.resize(length);
- this -> fitness = 0;
- std::uniform_int_distribution<std::size_t> distribution{0, sampleSpace.length() - 1};
- for (int i = 0; i < length; i++) {
- genes[i] = sampleSpace.at(distribution(random));
- }
- }
- //--------------------------------------------------------------------------
- DNA(const DNA &temp) {
- length = temp.length;
- fitness = 0;
- isDone = false;
- genes.clear();
- genes.resize(length);
- for (size_t i = 0; i < this -> length; i++) {
- this -> genes[i] = char(temp.genes[i]);
- }
- }
- //-----------------------------------------------------------------------------
- DNA operator=(const DNA &temp) {
- length = temp.length;
- fitness = 0;
- genes.clear();
- genes.resize(length);
- for (size_t i = 0; i < this -> length; i++) {
- this -> genes[i] = char(temp.genes[i]);
- }
- return *this;
- }
- //-----------------------------------------------------------------------
- void show() {
- for (int i = 0; i < length; i++) {
- std::cout<<genes[i];
- }
- std::cout<<"tfitness:"<<fitness;
- }
- //----------------------------------------------------------------------
- void calculateFitness(std::string target) {
- for (size_t i = 0; i < target.length(); i++) {
- if (genes[i] == target.at(i))
- fitness++;
- }
- if (fitness == target.length()) {
- isDone = true;
- }
- }
- //-----------------------------------------------------------------------
- float getFitness() {
- return this -> fitness;
- }
- //----------------------------------------------------------------------
- void mutate(float mutationRate) {
- std::uniform_int_distribution<size_t> sampleDist{0, sampleSpace.length() - 1};
- std::uniform_real_distribution<> randDist{0, 1};
- for (size_t i = 0; i < length; i++) {
- if (randDist(random) < mutationRate) {
- genes[i] = sampleSpace.at(sampleDist(random));
- }
- }
- }
- //------------------------------------------------------------------------
- DNA gimmeBaby() {
- return DNA(*this);
- }
- //-------------------------------------------------------------------------
- bool getStatus() {
- return isDone;
- }
- };
- std::mt19937 DNA::random{time(NULL)};
- #endif
- #ifndef POPULATION_HPP
- #define POPULATION_HPP
- #include <vector>
- #include <ctime>
- class Population {
- private :
- size_t size;
- std::vector<DNA> population;
- float mutationRate;
- std::string target;
- unsigned int fitnessSum;
- size_t generations;
- bool isDone;
- int bestDna;
- static std::mt19937 random;
- public:
- Population(size_t length, float mr, std::string t) {
- this -> size = length;
- this -> mutationRate = mr;
- this -> population.resize(size);
- this -> target = t;
- this -> fitnessSum = 0;
- this -> generations = 0;
- this -> isDone = false;
- this -> bestDna = 0;
- for (size_t i = 0; i < size; i++) {
- population[i].initialize(target.length());
- }
- }
- //------------------------------------------------------------------------------
- void show() {
- size_t len = size < 100 ? size : 100;
- for (size_t i = 0; i < len; i++) {
- population[i].show();
- }
- }
- //---------------------------------------------------------------------------------
- void calculateFitness() {
- for (size_t i = 0; i < size; i++) {
- population[i].calculateFitness(this -> target);
- }
- }
- //-----------------------------------------------------------------------------------
- void mutate() {
- for (size_t i = 0; i < size; i++) {
- population[i].mutate(this -> mutationRate);
- }
- }
- //--------------------------------------------------------------------------------------
- void calculateFitnessSum() {
- this -> fitnessSum = 0;
- for (size_t i = 0; i < size; i++) {
- fitnessSum += population[i].getFitness();
- }
- }
- //-------------------------------------------------------------------------------------
- void naturalSelection() {
- std::vector<DNA> newPopulation(size);
- DNA parent;
- //setBestDna();
- //newPopulation[0] = population[bestDna];
- this -> calculateFitnessSum();
- for (size_t i = 0; i < size; i++) {
- // select parent based on fitness
- parent = this -> selectParent();
- // get baby from him
- newPopulation[i] = parent.gimmeBaby();
- }
- this -> population = newPopulation;
- this -> generations++;
- }
- //---------------------------------------------------------------------------------------
- DNA selectParent() {
- std::uniform_real_distribution<> randDist{0, double(this -> fitnessSum)};
- float rand = randDist(random);
- size_t runningSum = 0;
- for (int i = 0; i < this -> size; i++) {
- runningSum += this -> population[i].getFitness();
- if (runningSum > rand) {
- return this -> population[i];
- }
- }
- // should never get to this point
- return DNA();
- }
- //-----------------------------------------------------------------------------------------
- size_t getGeneration() {
- return generations;
- }
- //-----------------------------------------------------------------------------------------
- void isTargetAchieved() {
- for (size_t i = 0; i < size; i++) {
- if (population[i].getStatus()) {
- isDone = true;
- break;
- }
- }
- }
- //----------------------------------------------------------------------------------------------
- bool getStatus() {
- return isDone;
- }
- //---------------------------------------------------------------------------------------------
- void setBestDna() {
- size_t max = 0;
- size_t index = 0;
- for (size_t i = 0; i < size; i++) {
- if (max < population[i].getFitness()) {
- max = population[i].getFitness();
- index = i;
- }
- }
- bestDna = index;
- }
- //-----------------------------------------------------------------------------------------------
- void showBest() {
- size_t max = 0;
- size_t index = 0;
- for (size_t i = 0; i < size; i++) {
- if (max < population[i].getFitness()) {
- max = population[i].getFitness();
- index = i;
- }
- }
- population[index].show();
- std::cout<<"tgen:"<<generations<<std::endl;
- }
- };
- std::mt19937 Population::random{time(NULL)};
- #endif
- #include <iostream>
- #include "DNA.hpp"
- #include "population.hpp"
- // genetic algorithm
- // initialize the population
- // calculate the fitness
- // natural selection
- // mutation
- // new generation
- void geneticAlgorithm(std::string target) {
- Population p(500, 0.01f, target);
- while(true) {
- p.calculateFitness();
- p.isTargetAchieved();
- p.showBest();
- if (p.getStatus()) {
- break;
- }
- p.naturalSelection();
- p.mutate();
- }
- }
- int main() {
- geneticAlgorithm(std::string{"Hardik Sharma"});
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement