radiate_core/
replacement.rs

1use super::{Chromosome, Genotype, Population, random_provider};
2use std::sync::Arc;
3
4/// Trait for replacement strategies in the algorithms.
5///
6/// This trait defines a method for replacing a member of the [Population] with a new individual
7/// after the current individual has been determined to be invalid. Typically, this is done by
8/// replacing the individual with a new one generated by the encoder. But in some cases, it may
9/// be desirable to replace the individual in a different way, such as by sampling from the
10/// [Population].
11pub trait ReplacementStrategy<C: Chromosome>: Send + Sync {
12    fn replace(
13        &self,
14        population: &Population<C>,
15        encoder: Arc<dyn Fn() -> Genotype<C> + Send + Sync>,
16    ) -> Genotype<C>;
17}
18
19/// Replacement strategy that replaces the individual with a new one generated by the encoder.
20/// This is the default replacement strategy used in genetic algorithms.
21pub struct EncodeReplace;
22
23impl<C: Chromosome> ReplacementStrategy<C> for EncodeReplace {
24    fn replace(
25        &self,
26        _: &Population<C>,
27        encoder: Arc<dyn Fn() -> Genotype<C> + Send + Sync>,
28    ) -> Genotype<C> {
29        encoder()
30    }
31}
32
33/// Replacement strategy that replaces the individual with a random member of the [Population].
34/// This can be useful in cases where the [Population] is large and diverse or when the
35/// chromosome grows or changes in size, thus encoding a new individual can result
36/// in a member that that lacks significant diversity.
37pub struct PopulationSampleReplace;
38
39impl<C: Chromosome + Clone> ReplacementStrategy<C> for PopulationSampleReplace {
40    fn replace(
41        &self,
42        population: &Population<C>,
43        _: Arc<dyn Fn() -> Genotype<C> + Send + Sync>,
44    ) -> Genotype<C> {
45        let random_member = random_provider::range(0..population.len());
46        population[random_member].genotype().clone()
47    }
48}