diff --git a/src/Chromosome.cpp b/src/Chromosome.cpp index 9027ff9..4d6648a 100644 --- a/src/Chromosome.cpp +++ b/src/Chromosome.cpp @@ -49,6 +49,8 @@ Chromosome::Chromosome(const Chromosome& other) { // reserve to other's size/capacity? + this->genes.reserve(other.genes.size()); + for (auto& ptr : other.genes) { this->genes.push_back(std::unique_ptr(Gene::copy(ptr.get()))); } @@ -60,6 +62,7 @@ Chromosome& Chromosome::operator=(const Chromosome& other) // reserve to other's size/capacity? this->genes.clear(); + this->genes.reserve(other.genes.size()); if (this != &other) { for (auto& ptr : other.genes) { diff --git a/src/Chromosome.cpp.old b/src/Chromosome.cpp.old deleted file mode 100644 index 59b3fde..0000000 --- a/src/Chromosome.cpp.old +++ /dev/null @@ -1,232 +0,0 @@ -#include "Chromosome.hpp" - -#include -#if __GNUC__ < 7 // gcc 7 will support clamp -namespace std { - template - T clamp(T v, T lo, T hi) - { - return std::min(hi, std::max(lo, v)); - } -} -#endif - -#include -#include - - - -// #include -sf::Vector2f Chromosome::size(0, 0); -float Chromosome::stddev_position = .1; -float Chromosome::stddev_radius = .1; -float Chromosome::stddev_color = 20; -std::minstd_rand* Chromosome::re; - -sf::CircleShape Chromosome::circle; - - -Chromosome::Chromosome() -{ - // this->genes is already empty - this->circle.setPointCount(36); -} - - -Chromosome::Chromosome(Chromosome& father, Chromosome& mother) : - Chromosome() -{ - std::uniform_int_distribution<> booldist(0, 1); - -// auto fpair = this->selectSegment(father.genes); -// auto mpair = this->selectSegment(mother.genes); - -// auto cur_it = this->genes.begin(); -// std::cout << std::distance(cur_it, father.genes.begin()) << std::endl; -// std::cout << std::distance(cur_it, mother.genes.begin()) << std::endl; -// cur_it = this->genes.insert(cur_it, fpair.second, father.genes.end()); -// cur_it = this->genes.insert(cur_it, mpair.first, mpair.second); -// cur_it = this->genes.insert(cur_it, father.genes.begin(), fpair.first); - -// if (booldist(*Chromosome::re)) { -// this->genes.insert(this->genes.begin(), fpair.second, father.genes.end()); -// this->genes.insert(this->genes.begin(), mpair.first, mpair.second); -// this->genes.insert(this->genes.begin(), father.genes.begin(), fpair.first); -// } else { -// this->genes.insert(this->genes.begin(), mpair.second, mother.genes.end()); -// this->genes.insert(this->genes.begin(), fpair.first, fpair.second); -// this->genes.insert(this->genes.begin(), mother.genes.begin(), mpair.first); -// } - - auto gene_father = this->selectGene(father.genes); - auto gene_mother = this->selectGene(mother.genes); - - if (booldist(*Chromosome::re)) { - this->genes.insert(this->genes.begin(), father.genes.begin(), gene_father); - this->genes.insert(this->genes.begin(), gene_mother, mother.genes.end()); - } else { - this->genes.insert(this->genes.begin(), mother.genes.begin(), gene_mother); - this->genes.insert(this->genes.begin(), gene_father, father.genes.end()); - } -} - - -void Chromosome::mutate() -{ - std::uniform_int_distribution<> mutatedist(0, 1); // 1/2 of the time, it mutates everytime! - std::uniform_int_distribution<> choicedist(0, 12); - while (mutatedist(*Chromosome::re)) { - int choice = choicedist(*Chromosome::re); - - if (choice < 1) { // add -// std::cout << "Added circle" << std::endl; - this->genes.push_back(this->randomGene()); - - } else if (choice < 2) { // remove -// std::cout << "Removed circle" << std::endl; - auto it = this->selectGene(this->genes); - if (it != this->genes.end()) { - this->genes.erase(it); - } - - } else if (choice < 4) { // swap -// std::cout << "Swapped circles" << std::endl; - auto it_one = this->selectGene(this->genes); - auto it_two = this->selectGene(this->genes); - if (it_one != this->genes.end() && it_two != this->genes.end() && it_one != it_two) { - auto tmp = *it_one; - *it_one = *it_two; - *it_two = tmp; - } - - } else { // mutate -// std::cout << "Mutated circle" << std::endl; - auto it = this->selectGene(this->genes); - if (it != this->genes.end()) { - this->mutateGene(*it); - } - } - } -} - - -void Chromosome::draw(sf::RenderTarget& target, sf::RenderStates states) const -{ - this->circle.setPosition(0, 0); - this->circle.setRadius(Chromosome::size.x + Chromosome::size.y); - this->circle.setOrigin(Chromosome::size); - this->circle.setFillColor(sf::Color::White); - target.draw(this->circle, states); - - for (auto gene : this->genes) { - Chromosome::circle.setPosition(gene.position); - Chromosome::circle.setRadius(gene.radius); - Chromosome::circle.setOrigin(sf::Vector2f(gene.radius, gene.radius)); - Chromosome::circle.setFillColor(gene.color); - target.draw(Chromosome::circle, states); - } -} - - -size_t Chromosome::length() -{ - return this->genes.size(); -} - - -float Chromosome::maxRadius() -{ - return std::min(Chromosome::size.x, Chromosome::size.y)/2; -} - - -Chromosome::Gene Chromosome::randomGene() -{ - float max_radius = this->maxRadius(); - std::uniform_real_distribution<> xdist(0, Chromosome::size.x); - std::uniform_real_distribution<> ydist(0, Chromosome::size.y); - std::uniform_real_distribution<> rdist(0, sqrt(max_radius)); - std::uniform_int_distribution<> colordist(0, 255); - - sf::Vector2f position(xdist(*Chromosome::re), ydist(*Chromosome::re)); - float radius = (pow(rdist(*Chromosome::re), 2)); - sf::Color color( - colordist(*Chromosome::re), - colordist(*Chromosome::re), - colordist(*Chromosome::re), - 150 - ); - - Chromosome::Gene gene; - gene.position = position; - gene.radius = radius; - gene.color = color; - - return gene; -} - - -void Chromosome::mutateGene(Gene& gene) -{ - std::uniform_int_distribution<> booldist(0, 1); - float max_radius = this->maxRadius(); - - if (booldist(*Chromosome::re)) { // position - std::normal_distribution<> posdist(0, Chromosome::stddev_position); - gene.position.x = std::clamp( - gene.position.x + posdist(*Chromosome::re)*max_radius, - 0, - Chromosome::size.x - ); - gene.position.y = std::clamp( - gene.position.y + posdist(*Chromosome::re)*max_radius, - 0, - Chromosome::size.y - ); - } - - if (booldist(*Chromosome::re)) { // radius - std::normal_distribution<> raddist(0, Chromosome::stddev_radius); - gene.radius = std::clamp( - gene.radius + pow(raddist(*Chromosome::re)*sqrt(max_radius), 2), - 0, - max_radius - ); - } - - if (booldist(*Chromosome::re)) { // color (all three values at the same time) - std::normal_distribution<> coldist(0, Chromosome::stddev_color); - gene.color.r = std::clamp(gene.color.r + coldist(*Chromosome::re), 0, 255); - gene.color.g = std::clamp(gene.color.g + coldist(*Chromosome::re), 0, 255); - gene.color.b = std::clamp(gene.color.b + coldist(*Chromosome::re), 0, 255); - gene.color.a = std::clamp(gene.color.a + coldist(*Chromosome::re), 0, 255); - } -} - - -std::pair::iterator, std::vector::iterator> -Chromosome::selectSegment(std::vector& genes) -{ - std::uniform_int_distribution<> randdist(0, genes.size()-1); - auto first = genes.begin() + randdist(*Chromosome::re); - auto second = genes.begin() + randdist(*Chromosome::re); - - if (first > second) { - std::swap(first, second); - } - - return std::pair::iterator, - std::vector::iterator>(first, second); -} - - -std::vector::iterator -Chromosome::selectGene(std::vector& genes) -{ - if (genes.empty()) { - return genes.end(); - } else { - std::uniform_int_distribution<> posdist(0, genes.size()-1); - return genes.begin() + posdist(*Chromosome::re); - } -} diff --git a/src/Chromosome.hpp.old b/src/Chromosome.hpp.old deleted file mode 100644 index 2366eb3..0000000 --- a/src/Chromosome.hpp.old +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - - - -class Chromosome : public sf::Drawable -{ -public: - static sf::Vector2f size; - static float stddev_position; // percent of max_radius - static float stddev_radius; // percent of max_radius - static float stddev_color; - static std::minstd_rand* re; - - Chromosome(); // create empty chromosome - Chromosome(Chromosome& father, Chromosome& mother); // crossover - - void mutate(); // randomly mutate chromosome's genes - - virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const; - - size_t length(); - -protected: - static sf::CircleShape circle; - - struct Gene - { - sf::Vector2f position; - float radius; - sf::Color color; - }; - - std::vector genes; - - float maxRadius(); - - Gene randomGene(); - void mutateGene(Gene& gene); - - std::pair::iterator, std::vector::iterator> - selectSegment(std::vector& genes); - - std::vector::iterator selectGene(std::vector& genes); -};