From b0da515139231fc9e9d585f29db3dc19c4de1a80 Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 14 Apr 2018 01:07:56 -0700 Subject: [PATCH] Added functions to control crossover rate and type --- Breeder.cpp | 22 +++++++++++++++------- Breeder.h | 8 +++++++- Enums.h | 15 ++++++++++++++- Population.cpp | 42 +++++++++++++++++++++++++++++++++++++++++- Population.h | 15 +++++++++++++++ 5 files changed, 92 insertions(+), 10 deletions(-) diff --git a/Breeder.cpp b/Breeder.cpp index f4d8fa0..0dce7a5 100644 --- a/Breeder.cpp +++ b/Breeder.cpp @@ -28,6 +28,7 @@ namespace BitEvolver std::shared_ptr Breeder::Breed( std::shared_ptr mama, std::shared_ptr papa, + Enums::CrossoverType crossover_type, double crossover_rate, double mutation_rate ) @@ -36,18 +37,15 @@ namespace BitEvolver std::shared_ptr kiddo; int bit_length; - // For now, don't crossover unless the bit lengths are identical + // bit_length = mama->GetBitCount(); - if ( papa->GetBitCount() != bit_length ) { - throw std::runtime_error("Breeder::Breed() - Incompatible parents"); - } // Directly copy the mama kiddo = std::shared_ptr(new Chromosome(this->random, bit_length)); *kiddo = *mama; // Apply crossover - this->ApplyCrossover(kiddo, papa, crossover_rate); + this->ApplyCrossover(kiddo, papa, crossover_type, crossover_rate); // Apply mutation this->Mutate(kiddo, mutation_rate); @@ -115,7 +113,12 @@ namespace BitEvolver } // - void Breeder::ApplyCrossover(std::shared_ptr kiddo, std::shared_ptr parent, double crossover_rate) + void Breeder::ApplyCrossover( + std::shared_ptr kiddo, + std::shared_ptr parent, + Enums::CrossoverType crossover_type, + double crossover_rate + ) { // int @@ -124,7 +127,12 @@ namespace BitEvolver i ; - // + // Only proceed if using sexual crossover + if (crossover_type != Enums::CrossoverType::Sexual) { + return; + } + + // For now, don't crossover unless the bit lengths are identical bits_count = kiddo->GetBitCount(); if ( parent->GetBitCount() != bits_count ) { throw std::runtime_error("Breeder::ApplyCrossover() - Parent incompatible with Kiddo (bit lengths don't match)"); diff --git a/Breeder.h b/Breeder.h index 7decf6e..40f4ed1 100644 --- a/Breeder.h +++ b/Breeder.h @@ -20,6 +20,7 @@ namespace BitEvolver std::shared_ptr Breed( std::shared_ptr mama, std::shared_ptr papa, + Enums::CrossoverType crossover_type, double crossover_rate, double mutation_rate ); @@ -35,7 +36,12 @@ namespace BitEvolver // int PickRandomCrossoverPoint(std::shared_ptr chromosome, double crossover_rate); - void ApplyCrossover(std::shared_ptr kiddo, std::shared_ptr parent, double crossover_rate); + void ApplyCrossover( + std::shared_ptr kiddo, + std::shared_ptr parent, + Enums::CrossoverType crossover_type, + double crossover_rate + ); }; }; diff --git a/Enums.h b/Enums.h index b108c2c..a3791c9 100644 --- a/Enums.h +++ b/Enums.h @@ -3,7 +3,20 @@ // - +namespace BitEvolver +{ + // + namespace Enums + { + // + enum class CrossoverType + { + // + None, + Sexual + }; + }; +}; #endif \ No newline at end of file diff --git a/Population.cpp b/Population.cpp index 6e5405f..31dfb91 100644 --- a/Population.cpp +++ b/Population.cpp @@ -149,6 +149,34 @@ namespace BitEvolver return fitness_average; } + // + void Population::SetCrossoverPoint(double p) + { + // + this->crossover_point = p; + } + + // + double Population::GetCrossoverPoint() + { + // + return this->crossover_point; + } + + // + void Population::SetCrossoverType(Enums::CrossoverType t) + { + // + this->crossover_type = t; + } + + // + Enums::CrossoverType Population::GetCrossoverType() + { + // + return this->crossover_type; + } + // void Population::SetMutationRate(double r) { @@ -156,6 +184,13 @@ namespace BitEvolver this->mutation_rate = r; } + // + double Population::GetMutationRate() + { + // + return this->mutation_rate; + } + // void Population::Evolve() { @@ -332,7 +367,12 @@ namespace BitEvolver papa = this->PickChromosomeForBreeding(); // - kiddo = this->breeder->Breed(mama, papa, BIT_EVOLVER_POPULATION_DEFAULT_CROSSOVER, this->mutation_rate); + kiddo = this->breeder->Breed( + mama, papa, + this->crossover_type, + this->crossover_point, + this->mutation_rate + ); return kiddo; } diff --git a/Population.h b/Population.h index 828422c..a37dd42 100644 --- a/Population.h +++ b/Population.h @@ -46,8 +46,14 @@ namespace BitEvolver double GetAverageFitness(); double GetAverageFitness(std::vector> _chromosomes); + // + void SetCrossoverPoint(double p); + double GetCrossoverPoint(); + void SetCrossoverType(Enums::CrossoverType t); + Enums::CrossoverType GetCrossoverType(); // void SetMutationRate(double r); + double GetMutationRate(); // void Evolve(); @@ -57,6 +63,13 @@ namespace BitEvolver void PrintPopulation(); void PrintPopulation(std::vector> _chromosomes); + // Constants + const static int DEFAULT_POPULATION_SIZE = 100; + const static int DEFAULT_MUTATION_RATE = 0.01; + // + const static Enums::CrossoverType DEFAULT_CROSSOVER_TYPE = Enums::CrossoverType::Sexual; + const static int DEFAULT_CROSSOVER_POINT = 0.7; + // private: @@ -68,6 +81,8 @@ namespace BitEvolver std::vector> chromosomes; int population_size; bool population_needs_sorting; + Enums::CrossoverType crossover_type; + double crossover_point; double mutation_rate; int evolution_number;