@@ 71,10 71,9 @@ where
&self.vec
}
- pub fn perturb(mut self, rng: &mut dyn RngCore, p: f64) -> Self
+ pub fn perturb(&mut self, rng: &mut dyn RngCore, p: f64)
{
self.vec.apply(|c| *c = if rng.random::<f64>() <= p { 1 - *c } else { *c });
- self
}
fn to_real_internal<'a, T: DoubleEndedIterator<Item = &'a i8>>(vec: T, len: usize, min: f64, max: f64) -> f64
@@ 9,7 9,7 @@ use crate::binary_string::BinaryString;
pub trait PerturbationOperator {
type Chromosome;
- fn perturb(self: &mut Self, chromosome: &Self::Chromosome) -> Self::Chromosome;
+ fn perturb(&mut self, chromosome: &mut Self::Chromosome);
}
pub struct BinaryStringBitPerturbation<D> {
@@ 35,8 35,8 @@ where
{
type Chromosome = BinaryString<D>;
- fn perturb(self: &mut Self, chromosome: &Self::Chromosome) -> Self::Chromosome {
- chromosome.clone().perturb(&mut self.rng, self.p)
+ fn perturb(&mut self, chromosome: &mut Self::Chromosome) {
+ chromosome.perturb(&mut self.rng, self.p);
}
}
@@ 89,8 89,8 @@ impl<const LEN: usize> RandomDistributionPerturbation<LEN, Uniform<f64>> {
impl<TDistribution: Distribution<f64>, const LEN: usize> PerturbationOperator for RandomDistributionPerturbation<LEN, TDistribution> {
type Chromosome = SVector<f64, LEN>;
- fn perturb(self: &mut Self, chromosome: &Self::Chromosome) -> Self::Chromosome {
- chromosome + Self::Chromosome::zeros().map(|_| self.distribution.sample(&mut self.rng))
+ fn perturb(&mut self, chromosome: &mut Self::Chromosome) {
+ *chromosome += Self::Chromosome::zeros().map(|_| self.distribution.sample(&mut self.rng));
}
}
@@ 111,9 111,7 @@ impl<const LEN: usize> PatternPerturbation<LEN> {
impl<const LEN: usize> PerturbationOperator for PatternPerturbation<LEN> {
type Chromosome = SVector::<f64, LEN>;
- fn perturb(self: &mut Self, chromosome: &Self::Chromosome) -> Self::Chromosome {
- let mut chromosome = chromosome.clone();
-
+ fn perturb(&mut self, chromosome: &mut Self::Chromosome) {
// 1. Choose dimension
let idx = self.rng.random_range(0..LEN);
// 2. Direction
@@ 125,8 123,6 @@ impl<const LEN: usize> PerturbationOperator for PatternPerturbation<LEN> {
// Apply
chromosome[idx] += d;
-
- chromosome
}
}
@@ 182,16 178,21 @@ impl<const LEN: usize, T: PerturbationOperator<Chromosome = SVector<f64, LEN>>>
chromosome
}
- fn retry_perturb(self: &mut Self, chromosome: &SVector<f64, LEN>, retries: Option<usize>) -> SVector<f64, LEN> {
- let perturbed = self.perturbation.perturb(chromosome);
+ fn retry_perturb(&mut self, chromosome: &mut SVector<f64, LEN>, retries: Option<usize>) {
+ let mut perturbed = chromosome.clone();
+ self.perturbation.perturb(&mut perturbed);
if self.within_bounds(&perturbed) {
- return perturbed;
+ *chromosome = perturbed;
+ return;
}
match retries {
- Some(0) | None => self.bound(perturbed),
- Some(retries) => self.retry_perturb(chromosome, Some(retries - 1))
+ Some(0) | None => *chromosome = self.bound(perturbed),
+ Some(retries) => {
+ *chromosome = perturbed;
+ self.retry_perturb(chromosome, Some(retries - 1));
+ }
}
}
}
@@ 202,7 203,7 @@ where
{
type Chromosome = SVector<f64, LEN>;
- fn perturb(self: &mut Self, chromosome: &Self::Chromosome) -> Self::Chromosome {
+ fn perturb(&mut self, chromosome: &mut Self::Chromosome) {
match self.strategy {
BoundedPerturbationStrategy::Trim => self.retry_perturb(chromosome, None),
BoundedPerturbationStrategy::Retry(retries) => self.retry_perturb(chromosome, Some(retries))
@@ 211,13 212,13 @@ where
}
/// Perform given perturbation only with given probability
-pub struct MutationPerturbation<T: Clone> {
+pub struct MutationPerturbation<T> {
perturbation: Box<dyn PerturbationOperator<Chromosome = T>>,
rng: Box<dyn RngCore>,
probability: f64
}
-impl<T: Clone> MutationPerturbation<T> {
+impl<T> MutationPerturbation<T> {
pub fn new(perturbation: Box<dyn PerturbationOperator<Chromosome = T>>, probability: f64) -> Self {
Self {
perturbation,
@@ 227,23 228,21 @@ impl<T: Clone> MutationPerturbation<T> {
}
}
-impl<T: Clone> PerturbationOperator for MutationPerturbation<T> {
+impl<T> PerturbationOperator for MutationPerturbation<T> {
type Chromosome = T;
- fn perturb(self: &mut Self, chromosome: &Self::Chromosome) -> Self::Chromosome {
+ fn perturb(&mut self, chromosome: &mut Self::Chromosome) {
if self.rng.random_bool(self.probability) {
- self.perturbation.perturb(chromosome)
- } else {
- chromosome.clone()
+ self.perturbation.perturb(chromosome);
}
}
}
-pub struct CombinedPerturbation<T: Clone> {
+pub struct CombinedPerturbation<T> {
perturbations: Vec<Box<dyn PerturbationOperator<Chromosome = T>>>,
}
-impl<T: Clone> CombinedPerturbation<T> {
+impl<T> CombinedPerturbation<T> {
pub fn new(perturbations: Vec<Box<dyn PerturbationOperator<Chromosome = T>>>) -> Self {
Self {
perturbations,
@@ 251,16 250,13 @@ impl<T: Clone> CombinedPerturbation<T> {
}
}
-impl<T: Clone> PerturbationOperator for CombinedPerturbation<T> {
+impl<T> PerturbationOperator for CombinedPerturbation<T> {
type Chromosome = T;
- fn perturb(self: &mut Self, chromosome: &Self::Chromosome) -> Self::Chromosome {
- let mut current_chromosome = chromosome.clone();
+ fn perturb(&mut self, chromosome: &mut Self::Chromosome) {
for perturbation in self.perturbations.iter_mut() {
- current_chromosome = perturbation.perturb(¤t_chromosome);
+ perturbation.perturb(chromosome);
}
-
- current_chromosome
}
}
@@ 272,9 268,10 @@ pub mod tests {
fn test_perturb() {
let mut rng = rand::rng();
+ let mut binary_string1 = BinaryString::new_dyn(vec![1, 1, 0, 0]);
+ binary_string1.perturb(&mut rng, 1.0);
assert_eq!(
- *BinaryString::new_dyn(vec![1, 1, 0, 0])
- .perturb(&mut rng, 1.0)
+ *binary_string1
.vec()
.iter()
.map(|&x| x)
@@ 282,10 279,10 @@ pub mod tests {
vec![0, 0, 1, 1]
);
-
+ let mut binary_string2 = BinaryString::new_dyn(vec![1, 1, 0, 0]);
+ binary_string2.perturb(&mut rng, 0.0);
assert_eq!(
- *BinaryString::new_dyn(vec![1, 1, 0, 0])
- .perturb(&mut rng, 0.0)
+ *binary_string2
.vec()
.iter()
.map(|&x| x)