13#if !defined(ULTRA_LAYERED_POPULATION_H)
14# error "Don't include this file directly, include the specific .h instead"
17#if !defined(ULTRA_LAYERED_POPULATION_TCC)
18#define ULTRA_LAYERED_POPULATION_TCC
23template<LayeredPopulation P>
24[[nodiscard]] std::size_t random_layer_index(
const P &p)
36 auto idx(random::sup(p.size()));
38 for (std::size_t layer(0);
const auto &l : p.range_of_layers())
47 return p.layers() - 1;
66 for (std::size_t l(0); l < p.params.population.
init_subgroups; ++l)
67 layers_.emplace_back(p);
80const typename layered_population<I>::layer_t &
81layered_population<I>::layer(std::size_t l)
const
83 Expects(l < layers());
84 return *std::next(layers_.begin(), l);
92typename layered_population<I>::layer_t &
93layered_population<I>::layer(std::size_t l)
95 Expects(l < layers());
96 return *std::next(layers_.begin(), l);
102template<Indiv
idual I>
103const typename layered_population<I>::layer_t &
104layered_population<I>::front()
const
107 return layers_.front();
113template<Indiv
idual I>
114typename layered_population<I>::layer_t &layered_population<I>::front()
117 return layers_.front();
123template<Indiv
idual I>
124const typename layered_population<I>::layer_t &
125layered_population<I>::back()
const
128 return layers_.back();
134template<Indiv
idual I>
135typename layered_population<I>::layer_t &layered_population<I>::back()
138 return layers_.back();
155template<Indiv
idual I>
156const I &layered_population<I>::operator[](coord c)
const
158 return layer(c.layer_index)[c.individual_coord];
175template<Indiv
idual I>
176I &layered_population<I>::operator[](coord c)
178 return layer(c.layer_index)[c.individual_coord];
181template<Indiv
idual I>
182auto layered_population<I>::range_of_layers()
const
184 return std::ranges::subrange(layers_.cbegin(), layers_.cend());
187template<Indiv
idual I>
188auto layered_population<I>::range_of_layers()
190 return std::ranges::subrange(layers_.begin(), layers_.end());
198template<Indiv
idual I>
199void layered_population<I>::init(layer_t &l)
202 l.allowed(problem().params.population.individuals);
204 std::generate_n(std::back_inserter(l), l.allowed(),
205 [
this] {return I(problem()); });
215template<Indiv
idual I>
216std::size_t layered_population<I>::layers() const noexcept
218 return layers_.size();
224template<Indiv
idual I>
225std::size_t layered_population<I>::size()
const
227 return std::ranges::fold_left(layers_, 0uz,
228 [](
auto accumulator,
const auto &l)
230 return accumulator + l.size();
237template<Indiv
idual I>
249template<Indiv
idual I>
250void layered_population<I>::add_layer()
253 const auto nl(layers());
256 layers_.emplace(layers_.begin(), problem());
259 Ensures(layers() == nl + 1);
269template<Indiv
idual I>
270bool layered_population<I>::erase(layer_t &l)
272 for (
auto it(layers_.begin()); it != layers_.end(); ++it)
273 if (std::addressof(l) == std::addressof(*it))
292template<Indiv
idual I>
293typename layered_population<I>::layer_iter
294layered_population<I>::erase(layer_iter pos)
296 Expects(iterator_of(pos, range_of_layers()));
297 return layers_.erase(pos);
304template<Indiv
idual I>
305typename layered_population<I>::const_iterator
306layered_population<I>::begin()
const
308 return const_iterator(*
this,
true);
315template<Indiv
idual I>
316typename layered_population<I>::const_iterator
317layered_population<I>::end()
const
319 return const_iterator(*
this,
false);
325template<Indiv
idual I>
326typename layered_population<I>::iterator layered_population<I>::begin()
328 return iterator(*
this,
true);
335template<Indiv
idual I>
336typename layered_population<I>::iterator layered_population<I>::end()
338 return iterator(*
this,
false);
344template<Indiv
idual I>
345void layered_population<I>::inc_age()
347 std::ranges::for_each(layers_, [](
auto &l) { l.inc_age(); });
360template<LayeredPopulation P>
361const auto &subgroup(
const P &p)
363 return p.layer(internal::random_layer_index(p));
374template<LayeredPopulation P>
375typename P::coord coord(
const P &p)
377 const auto layer_i(internal::random_layer_index(p));
378 return {layer_i, random::coord(p.layer(layer_i))};
390template<Indiv
idual I>
391bool layered_population<I>::load(std::istream &in)
393 std::size_t n_layers;
394 if (!(in >> n_layers))
397 layered_population<I> lp(problem(),
false);
399 for (std::size_t l(0); l < n_layers; ++l)
401 if (layer_t tmp; tmp.load(in, prob_->sset))
402 lp.layers_.push_back(std::move(tmp));
415template<Indiv
idual I>
416bool layered_population<I>::save(std::ostream &
out)
const
418 const auto n(layers());
422 for (
const auto &l : layers_)
432template<Indiv
idual I>
433bool layered_population<I>::is_valid()
const
435 for (
const auto &l : layers_)
441 ultraERROR(
"Undefined `problem`");
std::size_t init_subgroups
Definition parameters.h:68