@@ 1,4 1,4 @@
-use std::marker::PhantomData;
+use std::{any::Any, borrow::{Borrow, BorrowMut}, marker::PhantomData};
use nalgebra::{allocator::Allocator, DefaultAllocator, Dim, SVector};
use rand::{distr::Distribution, Rng, RngCore};
@@ 6,12 6,74 @@ use rand_distr::{uniform, Normal, NormalError, Uniform};
use crate::binary_string::BinaryString;
-pub trait PerturbationOperator {
+pub trait AnyPerturbationOperator: Any {
+ fn as_any(&self) -> &dyn Any;
+ fn as_any_mut(&mut self) -> &mut dyn Any;
+}
+
+pub trait PerturbationOperator: AnyPerturbationOperator {
type Chromosome;
fn perturb(&self, chromosome: &mut Self::Chromosome, rng: &mut dyn RngCore);
}
+impl<T: PerturbationOperator> AnyPerturbationOperator for T
+where
+ T: Any + 'static
+{
+ fn as_any(&self) -> &dyn Any {
+ self
+ }
+
+ fn as_any_mut(&mut self) -> &mut dyn Any {
+ self
+ }
+}
+
+pub trait WrapperPerturbation: PerturbationOperator {
+ fn borrow_any(&self) -> &dyn Any;
+ fn borrow_any_mut(&mut self) -> &mut dyn Any;
+
+ fn borrow<TPerturbation: 'static>(&self) -> Option<&TPerturbation> {
+ self.borrow_any().downcast_ref()
+ }
+
+ fn borrow_mut<TPerturbation: 'static>(&mut self) -> Option<&mut TPerturbation> {
+ self.borrow_any_mut().downcast_mut()
+ }
+}
+
+pub trait ListWrapperPerturbation: PerturbationOperator {
+ fn borrow_list_any<'a>(&'a self) -> impl Iterator<Item = &'a dyn Any>;
+ fn borrow_list_any_mut<'a>(&'a mut self) -> impl Iterator<Item = &'a mut dyn Any>;
+
+ fn borrow<'a, T: 'static>(&'a self, index: usize) -> Option<&'a T> {
+ self.borrow_list_any()
+ .nth(index)
+ .map(|perturbation| perturbation.downcast_ref())
+ .flatten()
+ }
+
+ fn borrow_mut<'a, T: 'static>(&'a mut self, index: usize) -> Option<&'a mut T> {
+ self.borrow_list_any_mut()
+ .nth(index)
+ .map(|perturbation| perturbation.downcast_mut())
+ .flatten()
+ }
+}
+
+pub struct IdentityPerturbation<TChromosome> {
+ _phantom: PhantomData<TChromosome>
+}
+
+impl<TChromosome: 'static> PerturbationOperator for IdentityPerturbation<TChromosome> {
+ type Chromosome = TChromosome;
+
+ fn perturb(&self, _: &mut Self::Chromosome, _: &mut dyn RngCore) {
+ // Do nothing.
+ }
+}
+
pub struct BinaryStringBitPerturbation<D> {
p: f64,
_phantom: PhantomData<D>
@@ 133,7 195,7 @@ impl<const LEN: usize> RandomDistributionPerturbation<LEN, Uniform<f64>> {
}
}
-impl<TDistribution: Distribution<f64>, const LEN: usize> PerturbationOperator for RandomDistributionPerturbation<LEN, TDistribution> {
+impl<TDistribution: Distribution<f64> + 'static, const LEN: usize> PerturbationOperator for RandomDistributionPerturbation<LEN, TDistribution> {
type Chromosome = SVector<f64, LEN>;
fn perturb(&self, chromosome: &mut Self::Chromosome, rng: &mut dyn RngCore) {
@@ 256,6 318,16 @@ where
}
}
+impl<const LEN: usize, T: PerturbationOperator<Chromosome = SVector<f64, LEN>> + 'static> WrapperPerturbation for BoundedPerturbation<LEN, T> {
+ fn borrow_any(&self) -> &dyn Any {
+ self.perturbation.as_any()
+ }
+
+ fn borrow_any_mut(&mut self) -> &mut dyn Any {
+ self.perturbation.as_any_mut()
+ }
+}
+
/// Perform given perturbation only with given probability
pub struct MutationPerturbation<T> {
perturbation: Box<dyn PerturbationOperator<Chromosome = T>>,
@@ 271,7 343,7 @@ impl<T> MutationPerturbation<T> {
}
}
-impl<T> PerturbationOperator for MutationPerturbation<T> {
+impl<T: 'static> PerturbationOperator for MutationPerturbation<T> {
type Chromosome = T;
fn perturb(&self, chromosome: &mut Self::Chromosome, rng: &mut dyn RngCore) {
@@ 281,6 353,16 @@ impl<T> PerturbationOperator for MutationPerturbation<T> {
}
}
+impl<T: 'static> WrapperPerturbation for MutationPerturbation<T> {
+ fn borrow_any(&self) -> &dyn Any {
+ self.perturbation.as_any()
+ }
+
+ fn borrow_any_mut(&mut self) -> &mut dyn Any {
+ self.perturbation.as_any_mut()
+ }
+}
+
pub struct CombinedPerturbation<T> {
perturbations: Vec<Box<dyn PerturbationOperator<Chromosome = T>>>,
}
@@ 293,7 375,7 @@ impl<T> CombinedPerturbation<T> {
}
}
-impl<T> PerturbationOperator for CombinedPerturbation<T> {
+impl<T: 'static> PerturbationOperator for CombinedPerturbation<T> {
type Chromosome = T;
fn perturb(&self, chromosome: &mut Self::Chromosome, rng: &mut dyn RngCore) {
@@ 303,6 385,16 @@ impl<T> PerturbationOperator for CombinedPerturbation<T> {
}
}
+impl<T: 'static> ListWrapperPerturbation for CombinedPerturbation<T> {
+ fn borrow_list_any<'a>(&'a self) -> impl Iterator<Item = &'a dyn Any> {
+ self.perturbations.iter().map(|p| p.as_any())
+ }
+
+ fn borrow_list_any_mut<'a>(&'a mut self) -> impl Iterator<Item = &'a mut dyn Any> {
+ self.perturbations.iter_mut().map(|p| p.as_any_mut())
+ }
+}
+
#[cfg(test)]
pub mod tests {
use crate::binary_string::BinaryString;