Finish implementing Chromosome and Gene

This commit is contained in:
Joscha 2017-05-08 07:33:51 +00:00
parent 82226ebd58
commit 693f9db274
3 changed files with 63 additions and 19 deletions

View file

@ -3,10 +3,10 @@
std::minstd_rand* Chromosome::re; std::minstd_rand* Chromosome::re;
std::unordered_set<Chromosome::GeneType> Chromosome::allowedGeneTypes; std::unordered_set<Gene::GeneType> Chromosome::allowedGeneTypes;
void Chromosome::allowGeneType(GeneType gt, bool allowed) void Chromosome::allowGeneType(Gene::GeneType gt, bool allowed)
{ {
if (allowed) { if (allowed) {
Chromosome::allowedGeneTypes.insert(gt); Chromosome::allowedGeneTypes.insert(gt);
@ -16,7 +16,7 @@ void Chromosome::allowGeneType(GeneType gt, bool allowed)
} }
bool Chromosome::isGeneTypeAllowed(GeneType gt) bool Chromosome::isGeneTypeAllowed(Gene::GeneType gt)
{ {
return Chromosome::allowedGeneTypes.find(gt) != Chromosome::allowedGeneTypes.end(); return Chromosome::allowedGeneTypes.find(gt) != Chromosome::allowedGeneTypes.end();
} }
@ -35,15 +35,12 @@ Chromosome::Chromosome(Chromosome& father, Chromosome& mother)
// reserve to father's size/capacity, and shrink_to_fit afterwards? // reserve to father's size/capacity, and shrink_to_fit afterwards?
Gene* geneptr;
for (auto it=father.genes.begin(); it!=split_father; ++it) { for (auto it=father.genes.begin(); it!=split_father; ++it) {
*geneptr = **it; this->genes.push_back(std::unique_ptr<Gene>(this->copyGene(it->get())));
this->genes.push_back(std::unique_ptr<Gene>(geneptr));
} }
for (auto it=split_mother; it!=mother.genes.end(); ++it) { for (auto it=split_mother; it!=mother.genes.end(); ++it) {
*geneptr = **it; this->genes.push_back(std::unique_ptr<Gene>(this->copyGene(it->get())));
this->genes.push_back(std::unique_ptr<Gene>(geneptr));
} }
} }
@ -93,8 +90,49 @@ std::vector<std::unique_ptr<Gene>>::iterator Chromosome::selectGene()
} }
Gene* Chromosome::copyGene(Gene* gene)
{
switch (gene->type) {
case Gene::Circle:
{
GeneCircle* newgene = new GeneCircle();
*newgene = *static_cast<GeneCircle*>(gene);
return newgene;
}
case Gene::Triangle:
{
GeneTriangle* newgene = new GeneTriangle();
*newgene = *static_cast<GeneTriangle*>(gene);
return newgene;
}
}
return nullptr;
}
Gene* Chromosome::createGene(Gene::GeneType type)
{
switch (type) {
case Gene::Circle:
return new GeneCircle();
case Gene::Triangle:
return new GeneTriangle();
}
return nullptr;
}
void Chromosome::addGene() void Chromosome::addGene()
{ {
std::uniform_int_distribution<> typedist(0, this->allowedGeneTypes.size()-1);
auto it = this->allowedGeneTypes.begin();
std::advance(it, typedist(*Gene::re));
const Gene::GeneType type = *it;
this->genes.push_back(std::unique_ptr<Gene>(this->createGene(type)));
} }
@ -113,9 +151,6 @@ void Chromosome::swapGenes()
auto it_two = this->selectGene(); auto it_two = this->selectGene();
if (it_one != this->genes.end() && it_two != this->genes.end() && it_one != it_two) { if (it_one != this->genes.end() && it_two != this->genes.end() && it_one != it_two) {
it_one->swap(*it_two); it_one->swap(*it_two);
// auto tmp = *it_one;
// *it_one = *it_two;
// *it_two = tmp;
} }
} }

View file

@ -12,15 +12,10 @@
class Chromosome : public sf::Drawable class Chromosome : public sf::Drawable
{ {
public: public:
enum GeneType
{
Circle
};
static std::minstd_rand* re; static std::minstd_rand* re;
static void allowGeneType(GeneType gt, bool allowed=true); static void allowGeneType(Gene::GeneType gt, bool allowed=true);
static bool isGeneTypeAllowed(GeneType gt); static bool isGeneTypeAllowed(Gene::GeneType gt);
Chromosome(); // create empty chromosome Chromosome(); // create empty chromosome
Chromosome(Chromosome& father, Chromosome& mother); // crossover Chromosome(Chromosome& father, Chromosome& mother); // crossover
@ -32,11 +27,13 @@ public:
size_t length() const; size_t length() const;
private: private:
static std::unordered_set<GeneType> allowedGeneTypes; static std::unordered_set<Gene::GeneType> allowedGeneTypes;
std::vector<std::unique_ptr<Gene>> genes; std::vector<std::unique_ptr<Gene>> genes;
std::vector<std::unique_ptr<Gene>>::iterator selectGene(); std::vector<std::unique_ptr<Gene>>::iterator selectGene();
Gene* copyGene(Gene* gene);
Gene* createGene(Gene::GeneType type);
void addGene(); void addGene();
void removeGene(); void removeGene();

View file

@ -12,6 +12,14 @@ public:
static std::minstd_rand* re; static std::minstd_rand* re;
static sf::Vector2f size; static sf::Vector2f size;
enum GeneType
{
Circle,
Triangle
};
GeneType type;
virtual ~Gene(); virtual ~Gene();
virtual void randomize() =0; virtual void randomize() =0;
@ -23,6 +31,8 @@ public:
class GeneCircle : public Gene class GeneCircle : public Gene
{ {
public: public:
GeneType type = Gene::Circle;
virtual ~GeneCircle(); virtual ~GeneCircle();
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const; virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
@ -51,6 +61,8 @@ private:
class GeneTriangle : public Gene class GeneTriangle : public Gene
{ {
public: public:
GeneType type = Gene::Triangle;
virtual ~GeneTriangle(); virtual ~GeneTriangle();
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const; virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;