neuroevolution_selection (faber_neuroevolution v1.2.4)

View Source

Selection strategies for neuroevolution.

This module provides different strategies for selecting which individuals survive to the next generation and which are used as parents for breeding.

Selection Strategies

All strategies expect individuals to have fitness values already calculated.

Summary

Functions

Uniform random selection.

Roulette wheel (fitness-proportionate) selection.

Select two parents for breeding.

Select top N individuals by fitness (truncation selection).

Types

fitness/0

-type fitness() :: float() | undefined.

generation/0

-type generation() :: non_neg_integer().

genome/0

-type genome() ::
          #genome{connection_genes ::
                      [#connection_gene{innovation :: pos_integer() | undefined,
                                        from_id :: term(),
                                        to_id :: term(),
                                        weight :: float(),
                                        enabled :: boolean()}],
                  input_count :: non_neg_integer(),
                  hidden_count :: non_neg_integer(),
                  output_count :: non_neg_integer()}.

individual/0

-type individual() ::
          #individual{id :: individual_id(),
                      network :: network(),
                      genome :: genome() | undefined,
                      parent1_id :: individual_id() | undefined,
                      parent2_id :: individual_id() | undefined,
                      fitness :: fitness(),
                      metrics :: metrics(),
                      generation_born :: generation(),
                      birth_evaluation :: non_neg_integer(),
                      max_age :: pos_integer(),
                      is_survivor :: boolean(),
                      is_offspring :: boolean()}.

individual_id/0

-type individual_id() :: term().

metrics/0

-type metrics() :: map().

mutation_config/0

-type mutation_config() ::
          #mutation_config{weight_mutation_rate :: float(),
                           weight_perturb_rate :: float(),
                           weight_perturb_strength :: float(),
                           add_node_rate :: float(),
                           add_connection_rate :: float(),
                           toggle_connection_rate :: float(),
                           add_sensor_rate :: float(),
                           add_actuator_rate :: float(),
                           mutate_neuron_type_rate :: float(),
                           mutate_time_constant_rate :: float()}.

network/0

-type network() :: term().

neuro_config/0

-type neuro_config() ::
          #neuro_config{population_size :: pos_integer(),
                        evaluations_per_individual :: pos_integer(),
                        selection_ratio :: float(),
                        mutation_rate :: float(),
                        mutation_strength :: float(),
                        reservoir_mutation_rate :: float() | undefined,
                        reservoir_mutation_strength :: float() | undefined,
                        readout_mutation_rate :: float() | undefined,
                        readout_mutation_strength :: float() | undefined,
                        topology_mutation_config :: mutation_config() | undefined,
                        max_evaluations :: pos_integer() | infinity,
                        max_generations :: pos_integer() | infinity,
                        target_fitness :: float() | undefined,
                        network_topology :: {pos_integer(), [pos_integer()], pos_integer()},
                        evaluator_module :: module(),
                        evaluator_options :: map(),
                        event_handler :: {module(), term()} | undefined,
                        meta_controller_config :: term() | undefined,
                        speciation_config :: speciation_config() | undefined,
                        realm :: binary(),
                        publish_events :: boolean(),
                        evaluation_mode :: direct | distributed | mesh,
                        mesh_config :: map() | undefined,
                        evaluation_timeout :: pos_integer(),
                        max_concurrent_evaluations :: pos_integer() | undefined,
                        strategy_config :: term() | undefined,
                        lc_chain_config :: term() | undefined,
                        checkpoint_interval :: pos_integer() | undefined,
                        checkpoint_config :: map() | undefined,
                        seed_networks :: [term()]}.

speciation_config/0

-type speciation_config() ::
          #speciation_config{enabled :: boolean(),
                             compatibility_threshold :: float(),
                             c1_excess :: float(),
                             c2_disjoint :: float(),
                             c3_weight_diff :: float(),
                             target_species :: pos_integer(),
                             threshold_adjustment_rate :: float(),
                             min_species_size :: pos_integer(),
                             max_stagnation :: non_neg_integer(),
                             species_elitism :: float(),
                             interspecies_mating_rate :: float()}.

Functions

random_select(Population)

-spec random_select(Population) -> Selected when Population :: [individual()], Selected :: individual().

Uniform random selection.

Selects a single individual uniformly at random. All individuals have equal probability regardless of fitness.

roulette_wheel(Population)

-spec roulette_wheel(Population) -> Selected when Population :: [individual()], Selected :: individual().

Roulette wheel (fitness-proportionate) selection.

Probability of selection is proportional to fitness. Higher fitness = higher probability of being selected.

Note: Handles negative fitness by shifting to positive range.

Uses tweann_nif:roulette_select/3 for NIF-accelerated selection.

Returns a single selected individual.

select_parents(Population, Config)

-spec select_parents(Population, Config) -> {Parent1, Parent2}
                        when
                            Population :: [individual()],
                            Config :: neuro_config(),
                            Parent1 :: individual(),
                            Parent2 :: individual().

Select two parents for breeding.

Uses roulette wheel selection to choose parents, ensuring that two different individuals are selected (if population allows).

top_n(Population, N)

-spec top_n(Population, N) -> Survivors
               when Population :: [individual()], N :: pos_integer(), Survivors :: [individual()].

Select top N individuals by fitness (truncation selection).

Sorts population by fitness descending and returns top N. This is elitist selection - only the best survive.

Example: %% Select top 10 individuals Survivors = neuroevolution_selection:top_n(Population, 10).

tournament(Population, TournamentSize, NumSelections)

-spec tournament(Population, TournamentSize, NumSelections) -> Selected
                    when
                        Population :: [individual()],
                        TournamentSize :: pos_integer(),
                        NumSelections :: pos_integer(),
                        Selected :: [individual()].

Tournament selection.

Randomly samples TournamentSize individuals from the population, returns the fittest one. Repeat to select multiple individuals.

Tournament selection provides moderate selection pressure while maintaining diversity.

Uses tweann_nif:tournament_select/2 for NIF-accelerated selection.

Example: %% Tournament of size 3 Winner = neuroevolution_selection:tournament(Population, 3, 1).