// #include "BitEvolver/Random.h" #include "BitEvolver/RouletteWheel.h" #include "BitEvolver/Chromosome.h" // #include #include #include #include #include // namespace BitEvolver { // using std::cout; using std::endl; // RouletteWheel::RouletteWheel() { // this->Instantiate(); // this->Reset(); } // void RouletteWheel::Reset() { // this->ClearChromosomes(); } // void RouletteWheel::ClearChromosomes() { // std::unique_lock lock(this->chromosomes_mutex); // this->chromosomes.clear(); this->ChromosomesChanged(); } // void RouletteWheel::SetChromosomes(std::vector> _chromosomes) { // std::unique_lock lock(this->chromosomes_mutex); // this->ClearChromosomes(); // this->chromosomes = _chromosomes; // this->ChromosomesChanged(); } // void RouletteWheel::AddChromosome(std::shared_ptr _chromosome) { // std::unique_lock lock(this->chromosomes_mutex); // this->chromosomes.push_back(_chromosome); this->ChromosomesChanged(); } // void RouletteWheel::AddChromosomes(std::vector> _chromosomes) { // std::unique_lock lock(this->chromosomes_mutex); // for ( std::shared_ptr _chromosome : _chromosomes ) { // this->chromosomes.push_back(_chromosome); } // this->ChromosomesChanged(); } // std::shared_ptr RouletteWheel::Spin() { // std::unique_lock lock(this->chromosomes_mutex); double range_min, range_max, spin ; size_t i; // this->PopulateSlots(); // if ( !this->wheel_slots.size() ) { return nullptr; } // Spin a random number in our range range_min = this->wheel_slots[0].first; range_max = this->wheel_slots[this->wheel_slots.size()-1].first; spin = this->random->GetDouble(range_min, range_max); // Find the corresponding chromosome for ( i=0; iwheel_slots.size(); i++ ) { if ( this->wheel_slots[i].first >= spin ) { return this->wheel_slots[i].second; } } // By default, return the first one I guess return this->wheel_slots[0].second; } // void RouletteWheel::Instantiate() { // this->random = std::shared_ptr( new Random() ); } // std::vector>> RouletteWheel::GetNormalizedChromosomeFitness() { // std::unique_lock lock(this->chromosomes_mutex); std::vector< std::pair< double, std::shared_ptr > > pairs; std::pair< double, std::shared_ptr > pair; double fitness, fitness_low, fitness_high ; // if ( !this->chromosomes.size() ) { return pairs; } // Locate lowest and highest fitness fitness_low = fitness_high = this->chromosomes[0]->GetFitness(); for ( std::shared_ptr chromosome : this->chromosomes ) { // fitness = chromosome->GetFitness(); if ( fitness > fitness_high ) { fitness_high = fitness; } if ( fitness < fitness_low ) { fitness_low = fitness; } } // Generate normalized pairs for ( std::shared_ptr chromosome : this->chromosomes ) { // pair.first = chromosome->GetFitness() - fitness_low; pair.first *= pair.first; // Square to enhance the difference a little pair.second = chromosome; // pairs.push_back(pair); // //cout << "[" << pair.first << "]" << chromosome->ToString() << endl; } return pairs; } // void RouletteWheel::SortChromosomes() { // std::unique_lock lock(this->chromosomes_mutex); // if ( !this->chromosomes_need_sorting ) { return; } // std::sort( this->chromosomes.begin(), this->chromosomes.end(), []( const std::shared_ptr& left, const std::shared_ptr& right ) -> bool { // if ( left->GetFitness() > right->GetFitness() ) { return true; } return false; } ); // this->chromosomes_need_sorting = false; } // void RouletteWheel::PopulateSlots() { // std::unique_lock lock(this->chromosomes_mutex); std::vector>> chromosomes_normalized_fitness; std::pair> wheel_slot; double slot_begin_value ; // if ( !this->slots_need_population ) { return; } // this->SortChromosomes(); // this->wheel_slots.clear(); // slot_begin_value = 0; chromosomes_normalized_fitness = this->GetNormalizedChromosomeFitness(); for ( std::pair> pair: chromosomes_normalized_fitness ) { // wheel_slot.first = pair.first + slot_begin_value; wheel_slot.second = pair.second; // this->wheel_slots.push_back(wheel_slot); // slot_begin_value += pair.first; } // this->slots_need_population = false; } // void RouletteWheel::ChromosomesChanged() { // this->chromosomes_need_sorting = true; this->slots_need_population = true; } };