genetic_algorithm/crossover/
rejuvenate.rs1use 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#[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}