Ultra 0.9.4
Loading...
Searching...
No Matches
layered_population.tcc
Go to the documentation of this file.
1
12
13#if !defined(ULTRA_LAYERED_POPULATION_H)
14# error "Don't include this file directly, include the specific .h instead"
15#endif
16
17#if !defined(ULTRA_LAYERED_POPULATION_TCC)
18#define ULTRA_LAYERED_POPULATION_TCC
19
20namespace internal
21{
22
23template<LayeredPopulation P>
24[[nodiscard]] std::size_t random_layer_index(const P &p)
25{
26 Expects(p.layers());
27 Expects(p.size());
28
29 // With multiple layers we cannot be sure that every layer has the same
30 // number of individuals. So the simple (and fast) solution:
31 //
32 // return random::sup(p.layers());
33 //
34 // isn't appropriate.
35
36 auto idx(random::sup(p.size()));
37
38 for (std::size_t layer(0); const auto &l : p.range_of_layers())
39 {
40 if (idx < l.size())
41 return layer;
42
43 idx -= l.size();
44 ++layer;
45 }
46
47 return p.layers() - 1;
48}
49
50} // namespace internal
51
59template<Individual I>
60layered_population<I>::layered_population(const ultra::problem &p,
61 bool init_subgroups)
62 : prob_(&p)
63{
64 if (init_subgroups)
65 {
66 for (std::size_t l(0); l < p.params.population.init_subgroups; ++l)
67 layers_.emplace_back(p);
68
69 assert(layers() == p.params.population.init_subgroups);
70 }
71
72 Ensures(is_valid());
73}
74
79template<Individual I>
80const typename layered_population<I>::layer_t &
81layered_population<I>::layer(std::size_t l) const
82{
83 Expects(l < layers());
84 return *std::next(layers_.begin(), l);
85}
86
91template<Individual I>
92typename layered_population<I>::layer_t &
93layered_population<I>::layer(std::size_t l)
94{
95 Expects(l < layers());
96 return *std::next(layers_.begin(), l);
97}
98
102template<Individual I>
103const typename layered_population<I>::layer_t &
104layered_population<I>::front() const
105{
106 Expects(layers());
107 return layers_.front();
108}
109
113template<Individual I>
114typename layered_population<I>::layer_t &layered_population<I>::front()
115{
116 Expects(layers());
117 return layers_.front();
118}
119
123template<Individual I>
124const typename layered_population<I>::layer_t &
125layered_population<I>::back() const
126{
127 Expects(layers());
128 return layers_.back();
129}
130
134template<Individual I>
135typename layered_population<I>::layer_t &layered_population<I>::back()
136{
137 Expects(layers());
138 return layers_.back();
139}
140
155template<Individual I>
156const I &layered_population<I>::operator[](coord c) const
157{
158 return layer(c.layer_index)[c.individual_coord];
159}
160
175template<Individual I>
176I &layered_population<I>::operator[](coord c)
177{
178 return layer(c.layer_index)[c.individual_coord];
179}
180
181template<Individual I>
182auto layered_population<I>::range_of_layers() const
183{
184 return std::ranges::subrange(layers_.cbegin(), layers_.cend());
185}
186
187template<Individual I>
188auto layered_population<I>::range_of_layers()
189{
190 return std::ranges::subrange(layers_.begin(), layers_.end());
191}
192
198template<Individual I>
199void layered_population<I>::init(layer_t &l)
200{
201 l.clear();
202 l.allowed(problem().params.population.individuals);
203
204 std::generate_n(std::back_inserter(l), l.allowed(),
205 [this] {return I(problem()); });
206}
207
215template<Individual I>
216std::size_t layered_population<I>::layers() const noexcept
217{
218 return layers_.size();
219}
220
224template<Individual I>
225std::size_t layered_population<I>::size() const
226{
227 return std::ranges::fold_left(layers_, 0uz,
228 [](auto accumulator, const auto &l)
229 {
230 return accumulator + l.size();
231 });
232}
233
237template<Individual I>
238const ultra::problem &layered_population<I>::problem() const
239{
240 Expects(prob_);
241 return *prob_;
242}
243
249template<Individual I>
250void layered_population<I>::add_layer()
251{
252#if !defined(NDEBUG)
253 const auto nl(layers());
254#endif
255
256 layers_.emplace(layers_.begin(), problem());
257
258#if !defined(NDEBUG)
259 Ensures(layers() == nl + 1);
260#endif
261}
262
269template<Individual I>
270bool layered_population<I>::erase(layer_t &l)
271{
272 for (auto it(layers_.begin()); it != layers_.end(); ++it)
273 if (std::addressof(l) == std::addressof(*it))
274 {
275 layers_.erase(it);
276 return true;
277 }
278
279 return false;
280}
281
292template<Individual I>
293typename layered_population<I>::layer_iter
294layered_population<I>::erase(layer_iter pos)
295{
296 Expects(iterator_of(pos, range_of_layers()));
297 return layers_.erase(pos);
298}
299
304template<Individual I>
305typename layered_population<I>::const_iterator
306layered_population<I>::begin() const
307{
308 return const_iterator(*this, true);
309}
310
315template<Individual I>
316typename layered_population<I>::const_iterator
317layered_population<I>::end() const
318{
319 return const_iterator(*this, false);
320}
321
325template<Individual I>
326typename layered_population<I>::iterator layered_population<I>::begin()
327{
328 return iterator(*this, true);
329}
330
335template<Individual I>
336typename layered_population<I>::iterator layered_population<I>::end()
337{
338 return iterator(*this, false);
339}
340
344template<Individual I>
345void layered_population<I>::inc_age()
346{
347 std::ranges::for_each(layers_, [](auto &l) { l.inc_age(); });
348}
349
350namespace random
351{
352
360template<LayeredPopulation P>
361const auto &subgroup(const P &p)
362{
363 return p.layer(internal::random_layer_index(p));
364}
365
374template<LayeredPopulation P>
375typename P::coord coord(const P &p)
376{
377 const auto layer_i(internal::random_layer_index(p));
378 return {layer_i, random::coord(p.layer(layer_i))};
379}
380
381} // namespace random
382
390template<Individual I>
391bool layered_population<I>::load(std::istream &in)
392{
393 std::size_t n_layers;
394 if (!(in >> n_layers))
395 return false;
396
397 layered_population<I> lp(problem(), false);
398
399 for (std::size_t l(0); l < n_layers; ++l)
400 {
401 if (layer_t tmp; tmp.load(in, prob_->sset))
402 lp.layers_.push_back(std::move(tmp));
403 else
404 return false;
405 }
406
407 *this = lp;
408 return true;
409}
410
415template<Individual I>
416bool layered_population<I>::save(std::ostream &out) const
417{
418 const auto n(layers());
419
420 out << n << '\n';
421
422 for (const auto &l : layers_)
423 if (!l.save(out))
424 return false;
425
426 return out.good();
427}
428
432template<Individual I>
433bool layered_population<I>::is_valid() const
434{
435 for (const auto &l : layers_)
436 if (!l.is_valid())
437 return false;
438
439 if (!prob_)
440 {
441 ultraERROR("Undefined `problem`");
442 return false;
443 }
444
445 return true;
446}
447
448#endif // include guard
std::size_t init_subgroups
Definition parameters.h:68
Definition problem.h:26