Switch to better roulette wheel selection

This commit is contained in:
Mike 2018-04-14 02:24:22 -07:00
parent a0fc0257ef
commit 4f1522ff43
2 changed files with 21 additions and 44 deletions

View File

@ -5,6 +5,7 @@
#include "BitEvolver/Random.h" #include "BitEvolver/Random.h"
#include "BitEvolver/Population.h" #include "BitEvolver/Population.h"
#include "BitEvolver/Breeder.h" #include "BitEvolver/Breeder.h"
#include "BitEvolver/RouletteWheel.h"
#include "BitEvolver/Chromosome.h" #include "BitEvolver/Chromosome.h"
@ -29,6 +30,7 @@ namespace BitEvolver
{ {
// //
this->InitRandomGenerator(); this->InitRandomGenerator();
this->InitRouletteWheel();
this->InitBreeder(); this->InitBreeder();
// //
@ -268,6 +270,15 @@ namespace BitEvolver
); );
} }
//
void Population::InitRouletteWheel()
{
//
this->roulette_wheel = std::shared_ptr<RouletteWheel>(
new RouletteWheel()
);
}
// //
void Population::InitBreeder() void Population::InitBreeder()
{ {
@ -313,6 +324,7 @@ namespace BitEvolver
void Population::BreedNewPopulation(std::shared_ptr<std::vector<std::shared_ptr<Chromosome>>> population_new, int size) void Population::BreedNewPopulation(std::shared_ptr<std::vector<std::shared_ptr<Chromosome>>> population_new, int size)
{ {
// //
std::shared_ptr<RouletteWheel> wheel;
std::vector<std::shared_ptr<std::thread>> threads; std::vector<std::shared_ptr<std::thread>> threads;
std::shared_ptr<std::thread> thread; std::shared_ptr<std::thread> thread;
int int
@ -320,6 +332,9 @@ namespace BitEvolver
i i
; ;
// First, populate the roulette wheel
this->roulette_wheel->SetChromosomes(this->chromosomes);
// //
thread_count = this->GetThreadCountSuggestion(); thread_count = this->GetThreadCountSuggestion();
@ -367,8 +382,8 @@ namespace BitEvolver
; ;
// Pick two parents // Pick two parents
mama = this->PickChromosomeForBreeding(); mama = this->roulette_wheel->Spin();
papa = this->PickChromosomeForBreeding(); papa = this->roulette_wheel->Spin();
// //
kiddo = this->breeder->Breed( kiddo = this->breeder->Breed(
@ -381,47 +396,6 @@ namespace BitEvolver
return kiddo; return kiddo;
} }
/**
(1) We want to pick the best chromosomes to repopulate
(2) [not in lecture] We want to add a bit of randomness
to the selection process, such that the worst chromosomes
can still possibly be picked, and the best can still
possibly be not-picked; Their fitness only increases
the probability they're picked.
*/
std::shared_ptr<Chromosome> Population::PickChromosomeForBreeding()
{
//
double normal;
int chromosome_index;
//
this->EnsureSortedPopulation();
/**
Grab normal with 0 at the mean, and the standard deviation equal
to 1/2 of the population size. Then make that an absolute value.
This will make top/best chromosomes more likely to be picked,
with the far/low end being much less likely
*/
#warning "Need to upgrade this to Roulette Wheel"
// Repeat as needed, since the normal generator might actually
// give us an out-of-bounds result sometimes
while ( true )
{
//
normal = this->random->GetNormal(0, 0.5);
chromosome_index = abs( normal * this->chromosomes.size()
);
if ( chromosome_index >= 0 && chromosome_index < (int)this->chromosomes.size() ) {
break;
}
}
//
return this->chromosomes[chromosome_index];
}
// //
int Population::GetThreadCountSuggestion() int Population::GetThreadCountSuggestion()
{ {

View File

@ -86,11 +86,15 @@ namespace BitEvolver
double mutation_rate; double mutation_rate;
int evolution_number; int evolution_number;
//
std::shared_ptr<class RouletteWheel> roulette_wheel;
// //
std::mutex breed_mutex; std::mutex breed_mutex;
// //
void InitRandomGenerator(); void InitRandomGenerator();
void InitRouletteWheel();
void InitBreeder(); void InitBreeder();
// //
@ -102,7 +106,6 @@ namespace BitEvolver
// //
std::shared_ptr<Chromosome> BreedChild(); std::shared_ptr<Chromosome> BreedChild();
std::shared_ptr<Chromosome> PickChromosomeForBreeding();
// //
int GetThreadCountSuggestion(); int GetThreadCountSuggestion();