radiate_engines/steps/
recombine.rs1use radiate_core::{
2 Alter, Chromosome, Ecosystem, MetricSet, Objective, Optimize, Population, Select,
3 engine::EngineStep,
4};
5use std::sync::Arc;
6
7pub struct RecombineStep<C: Chromosome> {
8 pub(crate) survivor_selector: Arc<dyn Select<C>>,
9 pub(crate) offspring_selector: Arc<dyn Select<C>>,
10 pub(crate) alters: Vec<Arc<dyn Alter<C>>>,
11 pub(crate) survivor_count: usize,
12 pub(crate) offspring_count: usize,
13 pub(crate) objective: Objective,
14}
15
16impl<C: Chromosome> RecombineStep<C> {
17 pub fn select_survivors(
18 &self,
19 population: &Ecosystem<C>,
20 metrics: &mut MetricSet,
21 ) -> Population<C> {
22 Self::select(
23 self.survivor_count,
24 &population.population,
25 &self.objective,
26 metrics,
27 &self.survivor_selector,
28 )
29 }
30
31 pub fn select_offspring(
32 &self,
33 count: usize,
34 population: &Population<C>,
35 metrics: &mut MetricSet,
36 ) -> Population<C> {
37 Self::select(
38 count,
39 &population,
40 &self.objective,
41 metrics,
42 &self.offspring_selector,
43 )
44 }
45
46 pub fn create_offspring(
47 &self,
48 generation: usize,
49 ecosystem: &Ecosystem<C>,
50 metrics: &mut MetricSet,
51 ) -> Population<C> {
52 if let Some(species) = ecosystem.species.as_ref() {
53 let total_offspring = self.offspring_count as f32;
54 let mut species_scores = species
55 .iter()
56 .filter_map(|spec| spec.score())
57 .collect::<Vec<_>>();
58
59 if let Objective::Single(Optimize::Minimize) = &self.objective {
60 species_scores.reverse();
61 }
62
63 let mut offspring = Vec::with_capacity(self.offspring_count);
64 for (species, score) in species.iter().zip(species_scores.iter()) {
65 let count = (score.as_f32() * total_offspring).round() as usize;
66 let mut selected_offspring =
67 self.select_offspring(count, &species.population, metrics);
68
69 self.objective.sort(&mut selected_offspring);
70
71 self.apply_alterations(generation, &mut selected_offspring, metrics);
72
73 offspring.extend(selected_offspring);
74 }
75
76 Population::new(offspring)
77 } else {
78 let mut offspring =
79 self.select_offspring(self.offspring_count, &ecosystem.population, metrics);
80
81 self.objective.sort(&mut offspring);
82
83 self.apply_alterations(generation, &mut offspring, metrics);
84 offspring
85 }
86 }
87
88 fn select(
89 count: usize,
90 population: &Population<C>,
91 objective: &Objective,
92 metrics: &mut MetricSet,
93 selector: &Arc<dyn Select<C>>,
94 ) -> Population<C> {
95 let timer = std::time::Instant::now();
96 let selected = selector.select(population, objective, count);
97
98 metrics.upsert_operations(selector.name(), selected.len() as f32, timer.elapsed());
99 selected
100 }
101
102 fn apply_alterations(
103 &self,
104 generation: usize,
105 offspring: &mut Population<C>,
106 metrics: &mut MetricSet,
107 ) {
108 self.alters.iter().for_each(|alt| {
109 alt.alter(offspring, generation)
110 .into_iter()
111 .for_each(|metric| {
112 metrics.upsert(metric);
113 });
114 });
115 }
116}
117
118impl<C> EngineStep<C> for RecombineStep<C>
119where
120 C: Chromosome,
121{
122 fn execute(
123 &mut self,
124 generation: usize,
125 metrics: &mut MetricSet,
126 ecosystem: &mut Ecosystem<C>,
127 ) {
128 let survivors = self.select_survivors(ecosystem, metrics);
129 let offspring = self.create_offspring(generation, ecosystem, metrics);
130
131 ecosystem.population_mut().clear();
132
133 survivors
134 .into_iter()
135 .chain(offspring.into_iter())
136 .for_each(|individual| {
137 ecosystem.population_mut().push(individual);
138 });
139 }
140}