3 #include <geneial/core/operations/selection/RouletteWheelSelection.h>
4 #include <geneial/core/population/chromosome/BaseChromosome.h>
5 #include <geneial/utility/Random.h>
12 geneial_private_namespace(geneial)
14 geneial_private_namespace(operation)
16 geneial_private_namespace(selection)
19 using ::geneial::population::Population;
20 using ::geneial::population::management::BaseManager;
21 using ::geneial::utility::Random;
23 geneial_export_namespace
28 template<
typename FITNESS_TYPE>
34 typedef typename BaseChromosome<FITNESS_TYPE>::ptr chrom_ptr_type;
36 typedef typename Population<FITNESS_TYPE>::fitnessmap_const_it const_pop_itr;
41 std::vector<std::pair<FITNESS_TYPE, chrom_ptr_type>> _ranges;
43 struct RouletteWheelComparator
45 bool operator()(
const std::pair<FITNESS_TYPE, chrom_ptr_type>& v1,
46 const std::pair<FITNESS_TYPE, chrom_ptr_type>& v2)
const
48 return v1.first < v2.first;
51 bool operator()(
const std::pair<FITNESS_TYPE, chrom_ptr_type>& v1,
const FITNESS_TYPE v2)
const
56 bool operator()(
const FITNESS_TYPE v1,
const FITNESS_TYPE v2)
const
61 bool operator()(
const FITNESS_TYPE v1,
const std::pair<FITNESS_TYPE, chrom_ptr_type>& v2)
const
69 constexpr
const static FITNESS_TYPE CONST_INC_BY = 1;
71 RouletteWheel(
const Population<FITNESS_TYPE> &population) :
75 _ranges.reserve(population.getSize());
78 const FITNESS_TYPE worstFitness = population.getFitnessMap().cbegin()->first;
79 FITNESS_TYPE positiveTranslation = 0;
83 positiveTranslation = std::abs(worstFitness);
86 for (
const auto &it : population.getFitnessMap())
92 _sum += std::abs(it.first);
99 _sum += positiveTranslation + it.first;
102 _ranges.emplace_back(_sum, it.second);
106 chrom_ptr_type spin(
double random)
108 return std::lower_bound(_ranges.begin(), _ranges.end(),
109 static_cast<FITNESS_TYPE
>(random * _sum),RouletteWheelComparator())->second;
115 template<
typename FITNESS_TYPE>
116 typename BaseSelectionOperation<FITNESS_TYPE>::selection_result_set RouletteWheelSelection<FITNESS_TYPE>::doSelect(
117 const Population<FITNESS_TYPE> &population, BaseManager<FITNESS_TYPE> &manager)
const
121 typedef typename BaseSelectionOperation<FITNESS_TYPE>::selection_result_set result_set;
122 typedef typename BaseChromosome<FITNESS_TYPE>::ptr chrom_ptr_type;
126 unsigned int left_select = this->getSettings().getNumberOfParents();
128 RouletteWheel<FITNESS_TYPE> rouletteWheel(population);
131 assert(population.getSize() >= left_select);
133 while (left_select > 0)
136 const bool allowDuplicates =
false;
141 const double random = Random::generate<double>(0.0, 1.0);
142 ptr = rouletteWheel.spin(random);
143 }
while (allowDuplicates || std::find(result.begin(), result.end(), ptr) != result.end());
145 result.emplace_back(ptr);