@@ 1,8 1,8 @@
use std::marker::PhantomData;
use nalgebra::{allocator::Allocator, DefaultAllocator, Dim};
use rand::{Rng, RngCore};
-use eoa_lib::perturbation::PerturbationOperator;
-use crate::tsp::NodePermutation;
+use eoa_lib::{fitness::FitnessFunction, perturbation::PerturbationOperator};
+use crate::tsp::{NodePermutation, TSPInstance};
pub struct SwapPerturbation<D> {
_phantom: PhantomData<D>
@@ 120,3 120,56 @@ where
}
}
}
+
+pub struct Random2OptPerturbation<D>
+where
+ D: Dim,
+ DefaultAllocator: nalgebra::allocator::Allocator<D, D>
+{
+ instance: TSPInstance<D>,
+ retries: usize,
+ reversal: ReverseSubsequencePerturbation<D>,
+ _phantom: PhantomData<D>
+}
+
+impl<D> Random2OptPerturbation<D>
+where
+ D: Dim,
+ DefaultAllocator: nalgebra::allocator::Allocator<D, D>
+{
+ pub fn new(instance: &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(),
+ reversal,
+ _phantom: PhantomData
+ }
+ }
+}
+
+impl<D> PerturbationOperator for Random2OptPerturbation<D>
+where
+ D: Dim,
+ DefaultAllocator: nalgebra::allocator::Allocator<D>,
+ DefaultAllocator: nalgebra::allocator::Allocator<D, D>,
+{
+ type Chromosome = NodePermutation<D>;
+
+ fn perturb(&self, chromosome: &mut Self::Chromosome, rng: &mut dyn RngCore) {
+ let original_fitness = self.instance.fit(chromosome).unwrap();
+
+ for _ in 0..self.retries {
+ let mut cloned = chromosome.clone();
+ self.reversal.perturb(&mut cloned, rng);
+ let new_fitness = self.instance.fit(&cloned).unwrap();
+ if new_fitness < original_fitness {
+ std::mem::swap(chromosome, &mut cloned);
+ return;
+ }
+ }
+ }
+}