Petri.Selection (petri v0.4.0)

Copy Markdown View Source

Representation-agnostic parent selection.

Selection operators work on {chromosome, fitness} pairs. One module serves all chromosome types.

select/3 draws population_size parents from the current population; select/4 draws an explicit count. Higher fitness = more likely to be selected.

Summary

Functions

Rank-based selection. Sorts the population by fitness and assigns selection probability by rank (not raw fitness value).

Fitness-proportional (roulette wheel) selection.

Dispatches to the named selection operator.

Selects exactly count parents from the population.

Stochastic Universal Sampling. Places population_size equally-spaced pointers on the roulette wheel.

Tournament selection. Picks tournament_size random individuals and returns the fittest. Repeat population_size times.

Functions

rank_selection(population, config)

Rank-based selection. Sorts the population by fitness and assigns selection probability by rank (not raw fitness value).

Resistant to outliers — a chromosome with 100× the fitness of the rest won't dominate the selection pool.

roulette_selection(population, config)

Fitness-proportional (roulette wheel) selection.

Each individual's selection probability is proportional to its fitness.

Raises when total fitness is zero after normalization.

select(selection, population, config)

Dispatches to the named selection operator.

Valid operators: :tournament, :roulette, :rank, :sus.

The config keyword list must contain :population_size. Tournament selection also reads :tournament_size (defaults to 3).

Example

iex> pop = [
...>   {%Petri.Chromosome.Binary{genes: [0, 0, 1]}, 1.0},
...>   {%Petri.Chromosome.Binary{genes: [1, 1, 0]}, 2.0},
...>   {%Petri.Chromosome.Binary{genes: [1, 1, 1]}, 3.0}
...> ]
iex> parents = Petri.Selection.select(:tournament, pop, [population_size: 2, tournament_size: 2])
iex> length(parents)
2

select(selection, population, config, count)

Selects exactly count parents from the population.

Same dispatch as select/3, with the number of picks explicit instead of read from :population_size in the config. Steady-state replacement uses this to draw just the two parents it needs.

Example

iex> pop = [
...>   {%Petri.Chromosome.Binary{genes: [0, 0, 1]}, 1.0},
...>   {%Petri.Chromosome.Binary{genes: [1, 1, 0]}, 2.0},
...>   {%Petri.Chromosome.Binary{genes: [1, 1, 1]}, 3.0}
...> ]
iex> parents = Petri.Selection.select(:tournament, pop, [tournament_size: 2], 2)
iex> length(parents)
2

stochastic_universal_sampling(population, config)

Stochastic Universal Sampling. Places population_size equally-spaced pointers on the roulette wheel.

Guarantees that very fit individuals are selected at least floor(p_i * n) times, giving lower variance than repeated roulette spins.

Negative fitness values are shifted via windowing so the minimum becomes a small positive value, preserving relative differences.

tournament_selection(population, config)

Tournament selection. Picks tournament_size random individuals and returns the fittest. Repeat population_size times.

Contestants are drawn independently, so an individual can be picked more than once per tournament.

Fast, works with negative fitness, and doesn't require fitness scaling.