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}