Ultra 0.9.4
Loading...
Searching...
No Matches
ultra::linear_population< I > Class Template Reference

#include <linear_population.h>

Public Types

using value_type = I
using const_iterator = typename std::vector<I>::const_iterator
using iterator = typename std::vector<I>::iterator
using difference_type = typename std::vector<I>::difference_type
using coord = std::size_t

Public Member Functions

 linear_population ()=default
 linear_population (const ultra::problem &)
I & operator[] (std::size_t)
const I & operator[] (std::size_t) const
std::size_t size () const noexcept
std::size_t safe_size () const
bool empty () const noexcept
std::size_t allowed () const noexcept
void allowed (std::size_t)
unsigned max_age () const noexcept
void max_age (unsigned) noexcept
void inc_age ()
void clear () noexcept
void push_back (const I &)
void pop_back ()
void reset (const ultra::problem &)
const_iterator begin () const noexcept
iterator begin () noexcept
const_iterator end () const noexcept
iterator end () noexcept
std::shared_mutex & mutex () const
bool load (std::istream &, const symbol_set &)
bool save (std::ostream &) const
population_uid uid () const noexcept
bool is_valid () const

Detailed Description

template<Individual I>
class ultra::linear_population< I >

A one-dimensional population of individuals.

Template Parameters
Ian individual type satisfying the Individual concept

A linear_population represents a collection of individuals organised as a single, flat sequence. Individuals may interact (for example, by mating or selection) to produce offspring.

The population enforces an upper bound (allowed()) and a lower bound on its size. The invariant:

min_allowed_ <= size() <= allowed()
std::size_t allowed() const noexcept
Definition linear_population.h:147
std::size_t size() const noexcept
Definition linear_population.h:90

is maintained whenever the object is in a valid state.

Thread safety

This class does not provide internal synchronisation for most operations. Clients are responsible for serialising concurrent access using the mutex returned by mutex().

Multiple threads may safely call const member functions concurrently, provided that no thread performs a modifying operation at the same time.

Mixing read-only access with modifiers, or invoking non-const member functions concurrently, requires external synchronisation.

The only method that is explicitly thread-safe is safe_size().

Copy semantics

Copying a population does not preserve its unique identifier (uid()), which is generated per application instance.

Constructor & Destructor Documentation

◆ linear_population() [1/2]

template<Individual I>
ultra::linear_population< I >::linear_population ( )
default

Constructs an empty population.

The population is created with default limits and contains no individuals.

◆ linear_population() [2/2]

template<Individual I>
linear_population::linear_population ( const ultra::problem & p)
explicit

Constructs a random population for a given problem.

Parameters
[in]pthe problem definition

The population size is initialised according to the problem parameters. Individuals are created using I(p).

Member Function Documentation

◆ allowed() [1/2]

template<Individual I>
std::size_t linear_population::allowed ( ) const
nodiscardnoexcept
Returns
the maximum number of allowed individuals
Note
size() <= allowed()

◆ allowed() [2/2]

template<Individual I>
void linear_population::allowed ( std::size_t n)

Sets the maximum number of allowed individuals.

Parameters
[in]nthe new maximum population size

If the population size exceeds the new limit, surplus individuals are removed from the end of the sequence.

The value is clamped so that it's never less than the minimum allowed population size.

◆ begin() [1/2]

template<Individual I>
linear_population< I >::const_iterator linear_population::begin ( ) const
nodiscardnoexcept
Returns
a const iterator to the first individual

◆ begin() [2/2]

template<Individual I>
linear_population< I >::iterator linear_population::begin ( )
nodiscardnoexcept
Returns
an iterator to the first individual

◆ clear()

template<Individual I>
void linear_population::clear ( )
noexcept

Removes all individuals from the population.

After this call size() == 0.

◆ empty()

template<Individual I>
bool linear_population::empty ( ) const
nodiscardnoexcept
Returns
true if the population is empty

◆ end() [1/2]

template<Individual I>
linear_population< I >::const_iterator linear_population::end ( ) const
nodiscardnoexcept
Returns
a const iterator past the last individual.

◆ end() [2/2]

template<Individual I>
linear_population< I >::iterator linear_population::end ( )
nodiscardnoexcept
Returns
an iterator past the last individual

◆ inc_age()

template<Individual I>
void linear_population::inc_age ( )

Increments the age of all individuals.

◆ is_valid()

template<Individual I>
bool linear_population::is_valid ( ) const
nodiscard

Checks the internal consistency of the population.

Returns
true if the population is internally consistent

◆ load()

template<Individual I>
bool linear_population::load ( std::istream & in,
const symbol_set & ss )
nodiscard

Loads the population from a stream.

Parameters
[in]ininput stream
[in]sssymbol_set used to rebuild individuals
Returns
true on success, false otherwise
Note
On failure, the population remains unchanged.

◆ max_age() [1/2]

template<Individual I>
unsigned linear_population::max_age ( ) const
nodiscardnoexcept
Returns
the maximum allowed age for individuals

◆ max_age() [2/2]

template<Individual I>
void linear_population::max_age ( unsigned m)
noexcept

Sets the reference maximum age.

Parameters
[in]mthe new maximum age

◆ mutex()

template<Individual I>
std::shared_mutex & linear_population::mutex ( ) const
nodiscard
Returns
the mutex protecting the population

This mutex must be used by clients to synchronise concurrent access to the population.

◆ operator[]() [1/2]

template<Individual I>
I & linear_population::operator[] ( std::size_t i)
nodiscard

Access an individual by index.

Parameters
[in]iindex of the individual
Returns
a reference to the individual at position i

◆ operator[]() [2/2]

template<Individual I>
const I & linear_population::operator[] ( std::size_t i) const
nodiscard

Access an individual by index (const).

Parameters
[in]iindex of the individual
Returns
a reference to the individual at position i

◆ pop_back()

template<Individual I>
void linear_population::pop_back ( )

Removes the last individual from the population.

Precondition
empty() == false

◆ push_back()

template<Individual I>
void linear_population::push_back ( const I & i)

Adds an individual to the population.

Parameters
[in]ithe individual to add

The individual is added only if the population size is strictly less than the allowed maximum.

◆ reset()

template<Individual I>
void linear_population::reset ( const ultra::problem & p)

Clears the population and creates a new random one.

Parameters
[in]pthe problem definition
Precondition
allowed() >= min_allowed_
Postcondition
size() == allowed()

Individuals are constructed using the provided problem definition. The number of created individuals equals allowed().

◆ safe_size()

template<Individual I>
std::size_t linear_population::safe_size ( ) const
nodiscard
Returns
number of individuals in this population
Remarks
Thread safe version of size().

◆ save()

template<Individual I>
bool linear_population::save ( std::ostream & out) const
nodiscard

Saves the population to a stream.

Parameters
[out]outoutput stream
Returns
true on success, false otherwise

◆ size()

template<Individual I>
std::size_t linear_population::size ( ) const
nodiscardnoexcept
Returns
number of individuals in this population

◆ uid()

template<Individual I>
population_uid linear_population::uid ( ) const
nodiscardnoexcept
Returns
a numerical unique identifier of this population
Note
The ID is unique within the current application instance.

The documentation for this class was generated from the following files: