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