Add Generation
Some more complex algorithms are not yet implemented.
This commit is contained in:
parent
0d686b2008
commit
2c37b90ad8
3 changed files with 156 additions and 1 deletions
3
Makefile
3
Makefile
|
|
@ -8,7 +8,8 @@ SOURCEFILES = cpp
|
||||||
SRCDIR = src
|
SRCDIR = src
|
||||||
TMPDIR = build
|
TMPDIR = build
|
||||||
TARGET = gross
|
TARGET = gross
|
||||||
FILES = Chromosome Fitness main
|
#FILES = Chromosome Fitness Generation main
|
||||||
|
FILES = Chromosome Fitness Generation main
|
||||||
|
|
||||||
#SOURCES = $(patsubst %,$(SRCDIR)/%.cpp,$(FILES))
|
#SOURCES = $(patsubst %,$(SRCDIR)/%.cpp,$(FILES))
|
||||||
OBJECTS = $(patsubst %,$(TMPDIR)/%.o,$(FILES))
|
OBJECTS = $(patsubst %,$(TMPDIR)/%.o,$(FILES))
|
||||||
|
|
|
||||||
97
src/Generation.cpp
Normal file
97
src/Generation.cpp
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
#include "Generation.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
size_t Generation::size = 500;
|
||||||
|
size_t Generation::living = Generation::size*0.25;
|
||||||
|
Fitness* Generation::fitness;
|
||||||
|
std::mt19937_64* Generation::re;
|
||||||
|
|
||||||
|
|
||||||
|
Generation::Generation()
|
||||||
|
{
|
||||||
|
this->individuals.reserve(Generation::size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Generation::updateFitness()
|
||||||
|
{
|
||||||
|
for (auto individual : this->individuals) {
|
||||||
|
if (!individual.fitnessEvaluated) {
|
||||||
|
individual.fitness = Generation::fitness->of(individual.chromosome);
|
||||||
|
individual.fitnessEvaluated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Generation::cull(CullType algorithm)
|
||||||
|
{
|
||||||
|
// sort by fitness
|
||||||
|
std::sort(
|
||||||
|
this->individuals.begin(),
|
||||||
|
this->individuals.end(),
|
||||||
|
[](Generation::Individual& a, Generation::Individual& b) -> bool {
|
||||||
|
return a.fitness < b.fitness;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// apply correct culling algorithm
|
||||||
|
switch (algorithm) {
|
||||||
|
case Generation::CUTOFF: this->cullCutoff(); break;
|
||||||
|
case Generation::ROULETTE: this->cullRoulette(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Generation::reproduce(float crossover)
|
||||||
|
{
|
||||||
|
// sort by fitness/available
|
||||||
|
std::sort(
|
||||||
|
this->individuals.begin(),
|
||||||
|
this->individuals.end(),
|
||||||
|
[](Generation::Individual& a, Generation::Individual& b) -> bool {
|
||||||
|
if (a.alive && b.alive) {
|
||||||
|
return a.fitness < b.fitness;
|
||||||
|
} else {
|
||||||
|
return a.alive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// reproduce according to parameters
|
||||||
|
std::uniform_int_distribution<> alivedist(0, Generation::living-1);
|
||||||
|
std::uniform_real_distribution<> crossoverdist(0, 1);
|
||||||
|
auto it = this->individuals.begin() + Generation::living;
|
||||||
|
for (; it!=this->individuals.end(); ++it) {
|
||||||
|
auto father = this->individuals.begin() + alivedist(*Generation::re);
|
||||||
|
|
||||||
|
if (crossoverdist(*Generation::re) <= crossover) {
|
||||||
|
auto mother = this->individuals.begin() + alivedist(*Generation::re);
|
||||||
|
it->chromosome = Chromosome(father->chromosome, mother->chromosome);
|
||||||
|
} else {
|
||||||
|
it->chromosome = father->chromosome;
|
||||||
|
}
|
||||||
|
|
||||||
|
it->alive = true;
|
||||||
|
it->fitness = 0;
|
||||||
|
it->fitnessEvaluated = false;
|
||||||
|
|
||||||
|
it->chromosome.mutate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Generation::cullCutoff()
|
||||||
|
{
|
||||||
|
auto it = this->individuals.begin() + Generation::living;
|
||||||
|
for (; it!=this->individuals.end(); ++it) {
|
||||||
|
it->alive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Generation::cullRoulette()
|
||||||
|
{
|
||||||
|
// TODO: implement this
|
||||||
|
}
|
||||||
57
src/Generation.hpp
Normal file
57
src/Generation.hpp
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
#include <vector>
|
||||||
|
#include "Chromosome.hpp"
|
||||||
|
#include "Fitness.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Generation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static size_t size;
|
||||||
|
static size_t living;
|
||||||
|
static Fitness* fitness;
|
||||||
|
static std::mt19937_64* re;
|
||||||
|
|
||||||
|
Generation();
|
||||||
|
|
||||||
|
enum CullType
|
||||||
|
{
|
||||||
|
CUTOFF,
|
||||||
|
ROULETTE
|
||||||
|
};
|
||||||
|
|
||||||
|
void updateFitness();
|
||||||
|
void cull(CullType algorithm=Generation::ROULETTE);
|
||||||
|
void reproduce(float crossover=0.5); // how often a child is the result of two parents,
|
||||||
|
// and not simply mutation.
|
||||||
|
|
||||||
|
struct Individual
|
||||||
|
{
|
||||||
|
// Individual(Chromosome& father, Chromosome& mother) : chromosome(father, mother) {}
|
||||||
|
|
||||||
|
Chromosome chromosome;
|
||||||
|
unsigned long long fitness = 0;
|
||||||
|
bool fitnessEvaluated = false;
|
||||||
|
bool alive = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Individual> individuals;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// all of the culling algorithms can assume:
|
||||||
|
// - sorted array
|
||||||
|
// - alive flag set to true on all individuals
|
||||||
|
void cullCutoff();
|
||||||
|
void cullRoulette();
|
||||||
|
|
||||||
|
// pool of Chromosomes
|
||||||
|
// sort pool?
|
||||||
|
// min/max/median
|
||||||
|
// extract stats
|
||||||
|
// calculate fitness
|
||||||
|
// cull/selection
|
||||||
|
// render full generation? No
|
||||||
|
};
|
||||||
Loading…
Add table
Add a link
Reference in a new issue