~ruther/ctu-fee-eoa

600d9ae9104b7ad3ce1c9abcdc089418720a09db — Rutherther a month ago bb0d963
feat: add mutation and combined perturbations
1 files changed, 54 insertions(+), 0 deletions(-)

M codes/eoa_lib/src/perturbation/mod.rs
M codes/eoa_lib/src/perturbation/mod.rs => codes/eoa_lib/src/perturbation/mod.rs +54 -0
@@ 210,6 210,60 @@ where
    }
}

/// Perform given perturbation only with given probability
pub struct MutationPerturbation<T: Clone> {
    perturbation: Box<dyn PerturbationOperator<Chromosome = T>>,
    rng: Box<dyn RngCore>,
    probability: f64
}

impl<T: Clone> MutationPerturbation<T> {
    pub fn new(perturbation: Box<dyn PerturbationOperator<Chromosome = T>>, probability: f64) -> Self {
        Self {
            perturbation,
            rng: Box::new(rand::rng()),
            probability
        }
    }
}

impl<T: Clone> PerturbationOperator for MutationPerturbation<T> {
    type Chromosome = T;

    fn perturb(self: &mut Self, chromosome: &Self::Chromosome) -> Self::Chromosome {
        if self.rng.random_bool(self.probability) {
            self.perturbation.perturb(chromosome)
        } else {
            chromosome.clone()
        }
    }
}

pub struct CombinedPerturbation<T: Clone> {
    perturbations: Vec<Box<dyn PerturbationOperator<Chromosome = T>>>,
}

impl<T: Clone> CombinedPerturbation<T> {
    pub fn new(perturbations: Vec<Box<dyn PerturbationOperator<Chromosome = T>>>) -> Self {
        Self {
            perturbations,
        }
    }
}

impl<T: Clone> PerturbationOperator for CombinedPerturbation<T> {
    type Chromosome = T;

    fn perturb(self: &mut Self, chromosome: &Self::Chromosome) -> Self::Chromosome {
        let mut current_chromosome = chromosome.clone();
        for perturbation in self.perturbations.iter_mut() {
            current_chromosome = perturbation.perturb(&current_chromosome);
        }

        current_chromosome
    }
}

#[cfg(test)]
pub mod tests {
    use crate::binary_string::BinaryString;