radiate_engines/builder/
problem.rs

1use crate::GeneticEngineBuilder;
2use radiate_core::{
3    Chromosome, Codec, Problem, Score,
4    fitness::{BatchFitnessFunction, FitnessFunction},
5};
6use std::sync::Arc;
7
8#[derive(Clone)]
9pub struct ProblemParams<C, T>
10where
11    C: Chromosome,
12    T: Clone,
13{
14    pub codec: Option<Arc<dyn Codec<C, T>>>,
15    pub problem: Option<Arc<dyn Problem<C, T>>>,
16    pub fitness_fn: Option<Arc<dyn Fn(T) -> Score + Send + Sync>>,
17    pub batch_fitness_fn: Option<Arc<dyn Fn(Vec<T>) -> Vec<Score> + Send + Sync>>,
18}
19
20impl<C, T> GeneticEngineBuilder<C, T>
21where
22    C: Chromosome + PartialEq + Clone,
23    T: Clone + Send,
24{
25    /// Set the codec that will be used to encode and decode the genotype of the population.
26    pub fn codec<D: Codec<C, T> + 'static>(mut self, codec: D) -> Self {
27        self.params.problem_params.codec = Some(Arc::new(codec));
28        self
29    }
30
31    /// Set the problem of the genetic engine. This is useful if you want to provide a custom problem.
32    pub fn problem<P: Problem<C, T> + 'static>(mut self, problem: P) -> Self {
33        self.params.problem_params.problem = Some(Arc::new(problem));
34        self
35    }
36
37    /// Set the fitness function of the genetic engine. This is the function that will be
38    /// used to evaluate the fitness of each individual in the population. This function should
39    /// take a single argument of type T and return a `Score`. The `Score` is used to
40    /// evaluate or rank the fitness of the individual.
41    ///
42    /// This method is required and must be set before calling the `build` method.
43    pub fn fitness_fn<S: Into<Score>>(
44        mut self,
45        fitness_func: impl FitnessFunction<T, S> + 'static,
46    ) -> Self {
47        let other = move |x| fitness_func.evaluate(x).into();
48        self.params.problem_params.fitness_fn = Some(Arc::new(other));
49        self
50    }
51
52    /// Set the batch fitness function of the genetic engine. This function will be used to
53    /// evaluate the fitness of a batch of individuals in the population. This function should
54    /// take a slice of type `&[T]` and return a `Vec<Score>`. The Score is used to
55    /// evaluate or rank the fitness of the individuals.
56    ///
57    /// This method is optional and can be set after calling the `build` method.
58    pub fn batch_fitness_fn<S: Into<Score>>(
59        mut self,
60        batch_fitness_func: impl BatchFitnessFunction<T, S> + 'static,
61    ) -> Self {
62        let other = move |x: Vec<T>| {
63            batch_fitness_func
64                .evaluate(x)
65                .into_iter()
66                .map(|s| s.into())
67                .collect()
68        };
69        self.params.problem_params.batch_fitness_fn = Some(Arc::new(other));
70        self
71    }
72}