genetic_algorithm/crossover/
rejuvenate.rs

1use super::Crossover;
2use crate::genotype::EvolveGenotype;
3use crate::strategy::evolve::{EvolveConfig, EvolveState};
4use crate::strategy::{StrategyAction, StrategyReporter, StrategyState};
5use rand::Rng;
6use std::marker::PhantomData;
7use std::time::Instant;
8
9/// Drop non-selected parents, then clone top parents to repopulate up to target_population_size,
10/// then rejuvenate selected parents to children in place. No copying of chromosomes for creating
11/// the offspring itself, only for repopulating the dropped non-selected parents (smaller fraction)
12/// Allowed for unique genotypes.
13#[derive(Clone, Debug)]
14pub struct Rejuvenate<G: EvolveGenotype> {
15    _phantom: PhantomData<G>,
16    pub selection_rate: f32,
17}
18impl<G: EvolveGenotype> Crossover for Rejuvenate<G> {
19    type Genotype = G;
20
21    fn call<R: Rng, SR: StrategyReporter<Genotype = G>>(
22        &mut self,
23        _genotype: &G,
24        state: &mut EvolveState<G>,
25        _config: &EvolveConfig,
26        _reporter: &mut SR,
27        _rng: &mut R,
28    ) {
29        let now = Instant::now();
30        let existing_population_size = state.population.chromosomes.len();
31        let selected_population_size =
32            (existing_population_size as f32 * self.selection_rate).ceil() as usize;
33        let dropped_population_size = (existing_population_size - selected_population_size).max(0);
34
35        state.population.truncate(selected_population_size);
36        state.population.extend_from_within(dropped_population_size);
37
38        state
39            .population
40            .chromosomes
41            .iter_mut()
42            .take(selected_population_size)
43            .for_each(|c| c.reset_age());
44        state.add_duration(StrategyAction::Crossover, now.elapsed());
45    }
46}
47
48impl<G: EvolveGenotype> Rejuvenate<G> {
49    pub fn new(selection_rate: f32) -> Self {
50        Self {
51            _phantom: PhantomData,
52            selection_rate,
53        }
54    }
55}