@@ 6,7 6,7 @@ use rand_distr::{uniform, Normal, NormalError, Uniform};
use crate::binary_string::BinaryString;
-pub trait AnyPerturbationOperator: Any {
+pub trait AsAny: Any {
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}
@@ 14,7 14,7 @@ pub trait AnyPerturbationOperator: Any {
pub enum Wrapped<'a, T> {
Single,
Wrapped(&'a dyn PerturbationOperator<Chromosome = T>),
- ListWrapped(Vec<&'a dyn PerturbationOperator<Chromosome = T>>),
+ ListWrapped(Vec<&'a (dyn PerturbationOperator<Chromosome = T>)>),
}
pub enum WrappedMut<'a, T> {
@@ 23,9 23,18 @@ pub enum WrappedMut<'a, T> {
ListWrapped(Vec<&'a mut dyn PerturbationOperator<Chromosome = T>>),
}
-pub trait PerturbationOperator: AnyPerturbationOperator {
+pub struct NoParams;
+pub trait PerturbationOperator {
type Chromosome;
+ fn try_get_params(&self) -> Option<&dyn Any> {
+ None
+ }
+
+ fn try_get_params_mut(&mut self) -> Option<&mut dyn Any> {
+ None
+ }
+
fn perturb(&self, chromosome: &mut Self::Chromosome, rng: &mut dyn RngCore);
fn wrapped(&self) -> Wrapped<'_, Self::Chromosome> {
@@ 37,9 46,7 @@ pub trait PerturbationOperator: AnyPerturbationOperator {
}
}
-impl<T: PerturbationOperator> AnyPerturbationOperator for T
-where
- T: Any + 'static
+impl<T: Any + 'static> AsAny for T
{
fn as_any(&self) -> &dyn Any {
self
@@ 53,7 60,7 @@ pub struct IdentityPerturbation<TChromosome> {
_phantom: PhantomData<TChromosome>
}
-impl<TChromosome: 'static> PerturbationOperator for IdentityPerturbation<TChromosome> {
+impl<TChromosome> PerturbationOperator for IdentityPerturbation<TChromosome> {
type Chromosome = TChromosome;
fn perturb(&self, _: &mut Self::Chromosome, _: &mut dyn RngCore) {
@@ 212,7 219,7 @@ impl<const LEN: usize> RandomDistributionPerturbation<LEN, Uniform<f64>> {
}
}
-impl<TDistribution: Distribution<f64> + 'static, const LEN: usize> PerturbationOperator for RandomDistributionPerturbation<LEN, TDistribution> {
+impl<TDistribution: Distribution<f64>, const LEN: usize> PerturbationOperator for RandomDistributionPerturbation<LEN, TDistribution> {
type Chromosome = SVector<f64, LEN>;
fn perturb(&self, chromosome: &mut Self::Chromosome, rng: &mut dyn RngCore) {
@@ 336,33 343,36 @@ where
}
/// Perform given perturbation only with given probability
-pub struct MutationPerturbation<T> {
- perturbation: Box<dyn PerturbationOperator<Chromosome = T>>,
+pub struct MutationPerturbationParams {
pub probability: f64
}
+pub struct MutationPerturbation<'a, T> {
+ perturbation: Box<dyn PerturbationOperator<Chromosome = T> + 'a>,
+ params: MutationPerturbationParams
+}
-impl<T: 'static> MutationPerturbation<T> {
- pub fn new(perturbation: Box<dyn PerturbationOperator<Chromosome = T>>, probability: f64) -> Self {
+impl<'a, T> MutationPerturbation<'a, T> {
+ pub fn new(perturbation: Box<dyn PerturbationOperator<Chromosome = T> + 'a>, probability: f64) -> Self {
Self {
perturbation,
- probability
+ params: MutationPerturbationParams { probability }
}
}
pub fn apply_to_mutations(
base_perturbation: &mut dyn PerturbationOperator<Chromosome = T>,
- apply: &mut dyn FnMut(&mut MutationPerturbation<T>)
+ apply: &mut dyn FnMut(&mut MutationPerturbationParams)
) {
apply_to_perturbations(base_perturbation, apply);
}
}
-pub fn apply_to_perturbations<T: 'static, U: PerturbationOperator<Chromosome = T>>(
+pub fn apply_to_perturbations<T, U: AsAny>(
base_perturbation: &mut dyn PerturbationOperator<Chromosome = T>,
apply: &mut dyn FnMut(&mut U)
) {
- if let Some(mutation) = base_perturbation.as_any_mut().downcast_mut::<U>() {
- apply(mutation);
+ if let Some(params) = base_perturbation.try_get_params_mut().map(|p| p.downcast_mut::<U>()).flatten() {
+ apply(params)
}
match base_perturbation.wrapped_mut() {
@@ 378,11 388,11 @@ pub fn apply_to_perturbations<T: 'static, U: PerturbationOperator<Chromosome = T
};
}
-impl<T: 'static> PerturbationOperator for MutationPerturbation<T> {
+impl<'a, T> PerturbationOperator for MutationPerturbation<'a, T> {
type Chromosome = T;
fn perturb(&self, chromosome: &mut Self::Chromosome, rng: &mut dyn RngCore) {
- if rng.random_bool(self.probability) {
+ if rng.random_bool(self.params.probability) {
self.perturbation.perturb(chromosome, rng);
}
}
@@ 394,21 404,29 @@ impl<T: 'static> PerturbationOperator for MutationPerturbation<T> {
fn wrapped_mut(&mut self) -> WrappedMut<'_, Self::Chromosome> {
WrappedMut::Wrapped(self.perturbation.as_mut())
}
+
+ fn try_get_params(&self) -> Option<&dyn Any> {
+ Some(self.params.as_any())
+ }
+
+ fn try_get_params_mut(&mut self) -> Option<&mut dyn Any> {
+ Some(self.params.as_any_mut())
+ }
}
-pub struct CombinedPerturbation<T> {
- perturbations: Vec<Box<dyn PerturbationOperator<Chromosome = T>>>,
+pub struct CombinedPerturbation<'a, T> {
+ perturbations: Vec<Box<dyn PerturbationOperator<Chromosome = T> + 'a>>,
}
-impl<T> CombinedPerturbation<T> {
- pub fn new(perturbations: Vec<Box<dyn PerturbationOperator<Chromosome = T>>>) -> Self {
+impl<'a, T> CombinedPerturbation<'a, T> {
+ pub fn new(perturbations: Vec<Box<dyn PerturbationOperator<Chromosome = T> + 'a>>) -> Self {
Self {
perturbations,
}
}
}
-impl<T: 'static> PerturbationOperator for CombinedPerturbation<T> {
+impl<'a, T> PerturbationOperator for CombinedPerturbation<'a, T> {
type Chromosome = T;
fn perturb(&self, chromosome: &mut Self::Chromosome, rng: &mut dyn RngCore) {
@@ 428,23 446,25 @@ impl<T: 'static> PerturbationOperator for CombinedPerturbation<T> {
WrappedMut::ListWrapped(
self.perturbations
.iter_mut()
- .map(|p| p.as_mut()).collect())
+ .map::<&mut (dyn PerturbationOperator<Chromosome = Self::Chromosome> + '_), _>
+ (|p| p.as_mut()).collect()
+ )
}
}
-pub struct OneOfPerturbation<T> {
- perturbations: Vec<Box<dyn PerturbationOperator<Chromosome = T>>>
+pub struct OneOfPerturbation<'a, T> {
+ perturbations: Vec<Box<dyn PerturbationOperator<Chromosome = T> + 'a>>
}
-impl<T> OneOfPerturbation<T> {
- pub fn new(perturbations: Vec<Box<dyn PerturbationOperator<Chromosome = T>>>) -> Self {
+impl<'a, T> OneOfPerturbation<'a, T> {
+ pub fn new(perturbations: Vec<Box<dyn PerturbationOperator<Chromosome = T> + 'a>>) -> Self {
Self {
perturbations
}
}
}
-impl<T: 'static> PerturbationOperator for OneOfPerturbation<T> {
+impl<'a, T> PerturbationOperator for OneOfPerturbation<'a, T> {
type Chromosome = T;
fn perturb(&self, chromosome: &mut Self::Chromosome, rng: &mut dyn RngCore) {
@@ 121,37 121,37 @@ where
}
}
-pub struct Random2OptPerturbation<D>
+pub struct Random2OptPerturbation<'a, D>
where
D: Dim,
DefaultAllocator: nalgebra::allocator::Allocator<D, D>
{
- instance: TSPInstance<D>,
+ instance: &'a TSPInstance<D>,
retries: usize,
reversal: ReverseSubsequencePerturbation<D>,
_phantom: PhantomData<D>
}
-impl<D> Random2OptPerturbation<D>
+impl<'a, D> Random2OptPerturbation<'a, D>
where
D: Dim,
DefaultAllocator: nalgebra::allocator::Allocator<D, D>
{
- pub fn new(instance: &TSPInstance<D>, retries: usize) -> Self {
+ pub fn new(instance: &'a TSPInstance<D>, retries: usize) -> Self {
let mut reversal = ReverseSubsequencePerturbation::new();
reversal.min_subsequence_len = 5;
reversal.max_subsequence_len = 15;
Self {
retries,
- instance: instance.clone(),
+ instance,
reversal,
_phantom: PhantomData
}
}
}
-impl<D> PerturbationOperator for Random2OptPerturbation<D>
+impl<'a, D> PerturbationOperator for Random2OptPerturbation<'a, D>
where
D: Dim,
DefaultAllocator: nalgebra::allocator::Allocator<D>,