44template <
typename Genotype,
typename FitnessT,
typename RNG>
46 size_t tournament_size, RNG& rng) {
47 if (population.empty()) {
48 throw std::invalid_argument(
"TournamentSelect: population must not be empty");
50 if (tournament_size == 0 || tournament_size > population.size()) {
51 throw std::invalid_argument(
52 "TournamentSelect: tournament_size must be in [1, population.size()]");
55 std::vector<size_t> indices(population.size());
56 std::iota(indices.begin(), indices.end(),
size_t{0});
57 std::shuffle(indices.begin(), indices.end(), rng);
59 size_t best_index = indices[0];
60 for (
size_t i = 1; i < tournament_size; ++i) {
61 if (population[indices[i]].fitness > population[best_index].fitness) {
62 best_index = indices[i];
79template <
typename Genotype,
typename FitnessT>
82 if (population.empty()) {
83 throw std::invalid_argument(
"RouletteSelectByDraw: population must not be empty");
86 for (
const auto& ind : population) {
87 if (ind.fitness < FitnessT{0}) {
88 throw std::invalid_argument(
"RouletteSelectByDraw: fitness must be non-negative");
92 if (!(total > FitnessT{0})) {
93 throw std::invalid_argument(
"RouletteSelectByDraw: total fitness must be positive");
95 if (draw < FitnessT{0} || draw >= total) {
96 throw std::invalid_argument(
"RouletteSelectByDraw: draw must be in [0, total_fitness)");
99 FitnessT cumulative{};
100 for (
size_t i = 0; i < population.size(); ++i) {
101 cumulative += population[i].fitness;
102 if (draw < cumulative) {
109 return population.size() - 1;
118template <
typename Genotype,
typename FitnessT,
typename RNG>
121 for (
const auto& ind : population) {
122 total += ind.fitness;
124 std::uniform_real_distribution<FitnessT> dist(FitnessT{0}, total);
139template <
typename Genotype,
typename FitnessT>
142 if (population.empty()) {
143 throw std::invalid_argument(
"RankSelectByDraw: population must not be empty");
146 std::vector<size_t> order(population.size());
147 std::iota(order.begin(), order.end(),
size_t{0});
148 std::sort(order.begin(), order.end(), [&population](
size_t a,
size_t b) {
149 return population[a].fitness < population[b].fitness;
152 const double n =
static_cast<double>(population.size());
153 const double total_weight = n * (n + 1.0) / 2.0;
154 if (draw < 0.0 || draw >= total_weight) {
155 throw std::invalid_argument(
"RankSelectByDraw: draw must be in [0, total_weight)");
158 double cumulative = 0.0;
159 for (
size_t i = 0; i < order.size(); ++i) {
160 cumulative +=
static_cast<double>(i + 1);
161 if (draw < cumulative) {
175template <
typename Genotype,
typename FitnessT,
typename RNG>
177 const double n =
static_cast<double>(population.size());
178 const double total_weight = n * (n + 1.0) / 2.0;
179 std::uniform_real_distribution<double> dist(0.0, total_weight);
PULSATRIX_ASSERT – debug-only invariant check for programmer errors, distinct from throw (used for ca...
#define PULSATRIX_ASSERT(cond)
Aborts with a diagnostic message if cond is false. Debug-only – use for conditions that indicate a bu...
Definition assert.hpp:22
A genetic-algorithm candidate solution: a genotype paired with its fitness.
Definition acquisition_functions.hpp:16
size_t RouletteSelect(const std::vector< Individual< Genotype, FitnessT > > &population, RNG &rng)
RNG-driven wrapper around RouletteSelectByDraw: draws uniformly from [0, total_fitness) and selects a...
Definition selection.hpp:119
size_t RankSelect(const std::vector< Individual< Genotype, FitnessT > > &population, RNG &rng)
RNG-driven wrapper around RankSelectByDraw: draws uniformly from [0, total_weight) and selects accord...
Definition selection.hpp:176
size_t RankSelectByDraw(const std::vector< Individual< Genotype, FitnessT > > &population, double draw)
Linear-rank selection given an explicit draw in [0, total_weight). Individuals are ranked ascending b...
Definition selection.hpp:140
size_t TournamentSelect(const std::vector< Individual< Genotype, FitnessT > > &population, size_t tournament_size, RNG &rng)
Tournament selection: draw tournament_size individuals without replacement from population and return...
Definition selection.hpp:45
size_t RouletteSelectByDraw(const std::vector< Individual< Genotype, FitnessT > > &population, FitnessT draw)
Fitness-proportionate ("roulette wheel") selection given an explicit draw in [0, total_fitness)....
Definition selection.hpp:80
A single candidate solution in a genetic algorithm population.
Definition individual.hpp:25