Ultra 0.9.4
Loading...
Searching...
No Matches
linear_population.h
Go to the documentation of this file.
1
12
13#if !defined(ULTRA_LINEAR_POPULATION_H)
14#define ULTRA_LINEAR_POPULATION_H
15
16#include "kernel/population.h"
17#include "kernel/problem.h"
18#include "kernel/random.h"
19
20#include "utility/misc.h"
21
22#include <algorithm>
23#include <mutex>
24#include <numeric>
25#include <shared_mutex>
26
27namespace ultra
28{
29
30///
31/// A one-dimensional population of individuals.
32///
33/// \tparam I an individual type satisfying the `Individual` concept
34///
35/// A `linear_population` represents a collection of individuals organised as a
36/// single, flat sequence. Individuals may interact (for example, by mating or
37/// selection) to produce offspring.
38///
39/// The population enforces an upper bound (`allowed()`) and a lower bound on
40/// its size. The invariant:
41///
42/// \code
43/// min_allowed_ <= size() <= allowed()
44/// \endcode
45///
46/// is maintained whenever the object is in a valid state.
47///
48/// ### Thread safety
49///
50/// This class does **not** provide internal synchronisation for most
51/// operations.
52/// Clients are responsible for serialising concurrent access using the mutex
53/// returned by `mutex()`.
54///
55/// Multiple threads may safely call `const` member functions concurrently,
56/// provided that no thread performs a modifying operation at the same time.
57///
58/// Mixing read-only access with modifiers, or invoking non-const member
59/// functions concurrently, requires external synchronisation.
60///
61/// The only method that is explicitly thread-safe is `safe_size()`.
62///
63/// ### Copy semantics
64///
65/// Copying a population does not preserve its unique identifier (`uid()`),
66/// which is generated per application instance.
67///
68template<Individual I>
70{
71public:
72 // ---- Member types ----
73 using value_type = I;
74 using const_iterator = typename std::vector<I>::const_iterator;
75 using iterator = typename std::vector<I>::iterator;
76 using difference_type = typename std::vector<I>::difference_type;
77 using coord = std::size_t;
78
79 // ---- Constructors ----
85 linear_population() = default;
86 explicit linear_population(const ultra::problem &);
87
88 // ---- Element access ----
89 [[nodiscard]] I &operator[](std::size_t);
90 [[nodiscard]] const I &operator[](std::size_t) const;
91
92 // ---- Capacity ----
93 [[nodiscard]] std::size_t size() const noexcept;
94 [[nodiscard]] std::size_t safe_size() const;
95 [[nodiscard]] bool empty() const noexcept;
96
97 [[nodiscard]] std::size_t allowed() const noexcept;
98 void allowed(std::size_t);
99
100 // ---- Age management ----
101 [[nodiscard]] unsigned max_age() const noexcept;
102 void max_age(unsigned) noexcept;
103 void inc_age();
104
105 // ---- Modifiers ----
106 void clear() noexcept;
107
108 void push_back(const I &);
109 void pop_back();
110
111 void reset(const ultra::problem &);
113 // ---- Iterators ----
114 [[nodiscard]] const_iterator begin() const noexcept;
115 [[nodiscard]] iterator begin() noexcept;
116 [[nodiscard]] const_iterator end() const noexcept;
117 [[nodiscard]] iterator end() noexcept;
118
119 // ---- Synchronisation ----
120 [[nodiscard]] std::shared_mutex &mutex() const;
121
122 // ---- Serialization ----
123 [[nodiscard]] bool load(std::istream &, const symbol_set &);
124 [[nodiscard]] bool save(std::ostream &) const;
125
126 // ---- Identification and validation ----
127 [[nodiscard]] population_uid uid() const noexcept;
128
129 [[nodiscard]] bool is_valid() const;
130
131private:
132 mutable ignore_copy<std::shared_mutex> mutex_ {};
133
134 std::vector<I> members_ {};
136 std::size_t allowed_ {std::numeric_limits<std::size_t>::max()};
137 std::size_t min_allowed_ {1};
138
139 unsigned max_age_ {std::numeric_limits<unsigned>::max()};
140
141 ignore_copy<app_level_uid> uid_ {};
142};
143
145
146} // namespace ultra
148#endif // include guard
void push_back(const I &)
Definition linear_population.h:211
std::size_t allowed() const noexcept
Definition linear_population.h:147
void pop_back()
Definition linear_population.h:223
const_iterator begin() const noexcept
Definition linear_population.h:234
unsigned max_age() const noexcept
Definition linear_population.h:112
bool save(std::ostream &) const
Definition linear_population.h:334
population_uid uid() const noexcept
Definition linear_population.h:353
bool empty() const noexcept
Definition linear_population.h:186
std::size_t size() const noexcept
Definition linear_population.h:90
void inc_age()
Definition linear_population.h:271
bool load(std::istream &, const symbol_set &)
Definition linear_population.h:286
void clear() noexcept
Definition linear_population.h:197
std::shared_mutex & mutex() const
Definition linear_population.h:135
I & operator[](std::size_t)
Definition linear_population.h:67
std::size_t safe_size() const
Definition linear_population.h:102
void reset(const ultra::problem &)
Definition linear_population.h:51
bool is_valid() const
Definition linear_population.h:364
const_iterator end() const noexcept
Definition linear_population.h:253
Definition symbol_set.h:115
STL namespace.
unsigned population_uid
Definition population.h:29
Definition problem.h:26