Ultra 0.9.4
Loading...
Searching...
No Matches
evolution_selection.tcc
Go to the documentation of this file.
1
12
13#if !defined(ULTRA_EVOLUTION_SELECTION_H)
14# error "Don't include this file directly, include the specific .h instead"
15#endif
16
17#if !defined(ULTRA_EVOLUTION_SELECTION_TCC)
18#define ULTRA_EVOLUTION_SELECTION_TCC
19
27template<Evaluator E>
28strategy<E>::strategy(E &eva, const parameters &params)
29 : eva_(eva), params_(params)
30{
31}
32
60template<Evaluator E>
61template<SizedRandomAccessPopulation P>
62std::vector<typename tournament<E>::scored_t>
63tournament<E>::operator()(const P &pop) const
64{
65 Expects(!this->params_.needs_init());
66
67 const auto rounds(this->params_.evolution.tournament_size);
68 assert(0 < rounds);
70
71 std::vector<std::pair<typename P::coord, evaluator_fitness_t<E>>> ret;
72 ret.reserve(rounds);
73
74 // This is the inner loop of an insertion sort algorithm. It's simple, fast
75 // (if `rounds` is small) and doesn't perform too much comparisons.
76 // DO NOT USE `std::sort` it's way slower.
77 const auto mate_zone(this->params_.evolution.mate_zone);
78 const auto target(random::coord(pop));
79
80 for (std::size_t i(0); i < rounds; ++i)
81 {
82 const auto new_coord(random::coord(pop, target, mate_zone));
83 const auto new_fitness(this->eva_(pop[new_coord]));
84
85 ret.emplace_back(new_coord, new_fitness);
86
87 auto k(i);
88 while (k && ret[k - 1].second < ret[k].second)
89 {
90 std::swap(ret[k - 1], ret[k]);
91 --k;
92 }
93 }
94
95 assert(std::ranges::is_sorted(ret,
96 [](const auto &i1, const auto &i2)
97 {
98 return i1.second > i2.second;
99 }));
100
101 std::vector<scored_t> rs;
102 rs.reserve(ret.size());
103 std::ranges::transform(ret, std::back_inserter(rs),
104 [&pop](const auto &c)
105 {
106 return scored_t{pop[c.first], c.second};
107 });
108
109 Ensures(rs.size() == rounds);
110 return rs;
111}
112
144template<Evaluator E>
145template<PopulationWithMutex P>
146std::array<typename alps<E>::scored_t, 2>
148{
149 Expects(!this->params_.needs_init());
150
151 struct candidate
152 {
153 evaluator_individual_t<E> ind;
154
155 // Extends the basic fitness with the age and takes advantage of the
156 // lexicographic comparison capabilities of `std::pair`.
157 std::pair<bool, evaluator_fitness_t<E>> rank;
158 };
159
160 const auto sample([this](const auto &layer)
161 {
162 auto ind(random::individual(layer));
163 const auto rank(std::pair(ind.age() <= layer.max_age(),
164 this->eva_(ind)));
165
166 return candidate{std::move(ind), rank};
167 });
168
169 auto best(sample(pops.primary()));
170 auto second(sample(pops.primary()));
171
172 if (best.rank < second.rank)
173 std::swap(best, second);
174
175 const auto ts(this->params_.evolution.tournament_size);
176 assert(0<ts && ts<=parameters::evolution_parameters::max_tournament_size);
177
178 const auto p_main_layer(this->params_.alps.p_main_layer);
179 assert(in_0_1(p_main_layer));
180
181 for (auto rounds(ts - 1); rounds; --rounds)
182 {
183 auto incoming(sample(pops.random(p_main_layer)));
184
185 if (second.rank < incoming.rank)
186 {
187 second = std::move(incoming);
188
189 if (best.rank < second.rank)
190 std::swap(best, second);
191 }
192
193 assert(best.rank >= second.rank);
194 assert(best.rank.first || !second.rank.first);
195 }
196
197 return {scored_t{std::move(best.ind), best.rank.second},
198 scored_t{std::move(second.ind), second.rank.second}};
199}
200
211template<SizedRandomAccessPopulation P>
212de::selected_refs<typename P::value_type>
213de::operator()(P &pop) const
214{
215 const auto target(random::coord(pop));
216 const auto base(random::coord(pop));
217 const auto a(random::coord(pop));
218 const auto b(random::coord(pop));
219
220 // We don't force constraints on indices.
221
222 return {pop[target], pop[base], pop[a], pop[b]};
223}
224
225#endif // include guard
Definition alps.h:48
constexpr Layer & primary() const noexcept
Definition alps.h:92
Layer & random(double p_pri) const
Definition alps.h:117
void operator()(alps_layer_pair< P >, const scored_t &, status_t &) const
Definition evolution_replacement.h:294
bool operator()(P &, const scored_t &, status_t &) const
Definition evolution_replacement.h:42
std::ranges::range_value_t< P > individual(const P &p)
Definition population.h:107
static constexpr std::size_t max_tournament_size
Definition parameters.h:180