Skip to main content

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}