1 #ifndef GRAIL_ROULETTE_SAMPLER_H
2 #define GRAIL_ROULETTE_SAMPLER_H
20 void Initialize(
const std::vector<std::unique_ptr<T>>& individuals);
22 std::vector<T*> SampleMany(
size_t count, std::mt19937_64& randGen);
23 std::vector<size_t> SampleManyIndices(
size_t count, std::mt19937_64& randGen);
24 T* Sample(std::mt19937_64& randGen);
25 size_t SampleIndex(std::mt19937_64& randGen);
26 size_t SampleIndexWithReturn(std::mt19937_64& randGen)
const;
29 std::vector<T*> data{};
30 double totalFitness = 0.0;
31 size_t RemoveIndex(
size_t index);
37 totalFitness -= data[index]->GetFitness();
38 data.erase(data.begin() + index);
43 inline void RouletteSampler<T>::Initialize(
const std::vector<std::unique_ptr<T>>& individuals)
47 for (
auto& individual : individuals)
49 totalFitness += individual->GetFitness();
50 data.push_back(individual.get());
55 inline RouletteSampler<T>::RouletteSampler()
61 inline RouletteSampler<T>::RouletteSampler(
const std::vector<std::unique_ptr<T>>& individuals)
63 Initialize(individuals);
67 inline size_t RouletteSampler<T>::SampleIndex(std::mt19937_64& randGen)
69 return RemoveIndex(SampleIndexWithReturn(randGen));
73 inline size_t RouletteSampler<T>::SampleIndexWithReturn(std::mt19937_64& randGen)
const
75 if (totalFitness <= std::numeric_limits<double>::epsilon())
76 return std::uniform_int_distribution<size_t>(0, data.size())(randGen);
78 double val = std::uniform_real_distribution<double>(0, totalFitness)(randGen);
79 for (
size_t i = 0; i < data.size(); ++i)
81 if (val < data[i]->GetFitness())
84 val -= data[i]->GetFitness();
86 return data.size() - 1;
90 inline std::vector<size_t> RouletteSampler<T>::SampleManyIndices(
size_t count, std::mt19937_64& randGen)
92 std::vector<size_t> retData;
93 if (count >= data.size())
95 retData.resize(data.size());
96 std::iota(retData.begin(), retData.end(), 0);
100 for (
size_t i = 0; i < count; ++i)
101 retData.push_back(SampleIndex(randGen));
107 inline T* RouletteSampler<T>::Sample(std::mt19937_64& randGen)
109 if (data.size() == 0)
112 size_t index = SampleIndexWithReturn(randGen);
113 T* individual = data[index];
119 inline std::vector<T*> RouletteSampler<T>::SampleMany(
size_t count, std::mt19937_64& randGen)
121 if (count >= data.size())
122 return std::vector<T*>(data);
124 std::vector<T*> retData;
125 for (
size_t i = 0; i < count; ++i)
126 retData.push_back(Sample(randGen));
Definition: RouletteSampler.hh:15