radiate_engines/builder/alters.rs
1use crate::GeneticEngineBuilder;
2use radiate_core::{Alterer, Chromosome, Crossover, Mutate};
3use radiate_utils::intern;
4
5impl<C, T> GeneticEngineBuilder<C, T>
6where
7 C: Chromosome + PartialEq + Clone,
8 T: Clone + Send,
9{
10 /// Set the alterer of the genetic engine. This is the alterer that will be used to
11 /// alter the offspring of the population. The alterer is used to apply mutations
12 /// and crossover operations to the offspring and will be used to create the next
13 /// generation of the population. **Note**: the order of the alterers is important - the
14 /// alterers will be applied in the order they are provided.
15 pub fn alter(mut self, alterers: Vec<Alterer<C>>) -> Self {
16 self.params.alterers = alterers.into_iter().map(|alt| alt.into()).collect();
17 self
18 }
19
20 /// Define a single mutator for the genetic engine - this will be converted to
21 /// a `Box<dyn Alter<C>>` and added to the list of alterers. Note: The order in which
22 /// mutators and crossovers are added is the order in which they will be applied during
23 /// the evolution process.
24 pub fn mutator<M: Mutate<C> + 'static>(mut self, mutator: M) -> Self {
25 self.params.alterers.push(mutator.alterer());
26 self
27 }
28
29 /// Define a list of mutators for the genetic engine - this will be converted to a list
30 /// of `Box<dyn Alter<C>>` and added to the list of alterers. Just like adding a single mutator,
31 /// the order in which mutators and crossovers are added is the order in which they will be applied
32 /// during the evolution process.s
33 pub fn mutators(mut self, mutators: Vec<Box<dyn Mutate<C>>>) -> Self {
34 let mutate_actions = mutators
35 .into_iter()
36 .map(|m| Alterer::Mutate(intern!(m.name()), m.rate(), m.into()))
37 .collect::<Vec<_>>();
38
39 self.params.alterers.extend(mutate_actions);
40 self
41 }
42
43 /// Define a single crossover for the genetic engine - this will be converted to
44 /// a `Box<dyn Alter<C>>` and added to the list of alterers. Note: The order in which
45 /// mutators and crossovers are added is the order in which they will be applied during
46 /// the evolution process.s
47 pub fn crossover<R: Crossover<C> + 'static>(mut self, crossover: R) -> Self {
48 self.params.alterers.push(crossover.alterer());
49 self
50 }
51
52 /// Define a list of crossovers for the genetic engine - this will be converted to a list
53 /// of `Box<dyn Alter<C>>` and added to the list of alterers. Just like adding a single crossover,
54 /// the order in which mutators and crossovers are added is the order in which they will be applied
55 /// during the evolution process.
56 pub fn crossovers(mut self, crossovers: Vec<Box<dyn Crossover<C>>>) -> Self {
57 let crossover_actions = crossovers
58 .into_iter()
59 .map(|c| Alterer::Crossover(c.name().leak(), c.rate(), c.into()))
60 .collect::<Vec<_>>();
61
62 self.params.alterers.extend(crossover_actions);
63 self
64 }
65}