Skip to main content

roma_lib/operator/
traits.rs

1use crate::solution::Solution;
2use crate::utils::random::Random;
3
4/// Base trait for all operators in the framework.
5/// Operators transform solutions in some way (mutation, crossover, selection, etc.)
6pub trait Operator {
7    /// Returns the name of the operator for debugging/logging purposes
8    fn name(&self) -> &str;
9}
10
11/// Trait for mutation operators that modify a single solution.
12///
13/// # Type Parameters
14/// * `T` - Type of the solution variables
15pub trait MutationOperator<T, Q = f64>: Operator
16where
17    T: Clone,
18    Q: Clone,
19{
20    /// Applies the mutation to a solution, modifying it in place.
21    ///
22    /// # Arguments
23    /// * `solution` - The solution to mutate
24    /// * `probability` - Probability of mutation (0.0 to 1.0)
25    /// * `rng` - Random generator provided by the algorithm
26    fn execute(&self, solution: &mut Solution<T, Q>, probability: f64, rng: &mut Random);
27}
28
29/// Trait for crossover operators that combine two parent solutions.
30///
31/// # Type Parameters
32/// * `T` - Type of the solution variables
33pub trait CrossoverOperator<T, Q = f64>: Operator
34where
35    T: Clone,
36    Q: Clone,
37{
38    /// Applies crossover to two parent solutions and returns offspring.
39    ///
40    /// # Arguments
41    /// * `parent1` - First parent solution
42    /// * `parent2` - Second parent solution
43    /// * `rng` - Random generator provided by the algorithm
44    ///
45    /// # Returns
46    /// A vector of offspring solutions (typically 1 or 2)
47    fn execute(
48        &self,
49        parent1: &Solution<T, Q>,
50        parent2: &Solution<T, Q>,
51        rng: &mut Random,
52    ) -> Vec<Solution<T, Q>>;
53
54    /// Applies crossover to several parent solutions and returns offspring.
55    ///
56    /// # Arguments
57    /// * `parents` - Vector of parent solutions
58    /// * `rng` - Random generator provided by the algorithm
59    ///
60    /// # Returns
61    /// A vector of offspring solutions (typically 1 or 2)
62    fn execute_several(
63        &self,
64        parents: Vec<Solution<T, Q>>,
65        _rng: &mut Random,
66    ) -> Vec<Solution<T, Q>> {
67        let mut offspring_result = vec![];
68        for i in 1..parents.len() {
69            offspring_result.push(parents[i].clone());
70        }
71        offspring_result
72    }
73
74    /// Returns the expected number of offspring produced by this operator
75    fn number_of_offspring(&self) -> usize {
76        2
77    }
78}
79
80/// Trait for selection operators that choose solutions from a population.
81///
82/// # Type Parameters
83/// * `T` - Type of the solution variables
84pub trait SelectionOperator<T, Q = f64>: Operator
85where
86    T: Clone,
87    Q: Clone,
88{
89    /// Selects a solution from a population.
90    ///
91    /// # Arguments
92    /// * `population` - The population to select from
93    /// * `rng` - Random generator provided by the algorithm
94    /// * `dominates` - Function to determine if one solution dominates another
95    ///
96    /// # Returns
97    /// A reference to the selected solution
98    fn execute<'a>(
99        &self,
100        population: &'a [Solution<T, Q>],
101        rng: &mut Random,
102        dominates: &dyn Fn(&Solution<T, Q>, &Solution<T, Q>) -> bool,
103    ) -> &'a Solution<T, Q>;
104
105    /// Selects multiple solutions from a population.
106    ///
107    /// # Arguments
108    /// * `population` - The population to select from
109    /// * `count` - Number of solutions to select
110    /// * `rng` - Random generator provided by the algorithm
111    ///
112    /// # Returns
113    /// A vector of references to selected solutions
114    fn select_many<'a>(
115        &self,
116        population: &'a [Solution<T, Q>],
117        count: usize,
118        rng: &mut Random,
119        dominates: fn(&Solution<T, Q>, &Solution<T, Q>) -> bool,
120    ) -> Vec<&'a Solution<T, Q>> {
121        (0..count)
122            .map(|_| self.execute(population, rng, &dominates))
123            .collect()
124    }
125}