From e3d7f2139691f8df389f621703c3a7827d765fbf Mon Sep 17 00:00:00 2001 From: Rutherther Date: Fri, 31 Oct 2025 15:56:23 +0100 Subject: [PATCH] feat(tsp): allow crossing bounds in reverse subsequence perturbation Currently subsequence perturbation was capable only of changes inside of bounds (left, right), but allow it going through the right bound, ie. from element 8 to element 1 - swapping 8 with 1, 9 with 0, 10 with 10... this generalizes the perturbation. Also, change the behavior to generate an index and a length instead of two indices. This allows for constraining the length of subsequences. --- codes/tsp_hw01/src/tsp.rs | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/codes/tsp_hw01/src/tsp.rs b/codes/tsp_hw01/src/tsp.rs index 9d826e4e34d43217beaaabad351c07f1cf5cf66d..d95714b4ffb9e22d4a439712ff29df113b3c6325 100644 --- a/codes/tsp_hw01/src/tsp.rs +++ b/codes/tsp_hw01/src/tsp.rs @@ -266,12 +266,18 @@ where } pub struct ReverseSubsequencePerturbation { - _phantom: PhantomData + _phantom: PhantomData, + min_subsequence_len: usize, + max_subsequence_len: usize, } impl ReverseSubsequencePerturbation { pub fn new() -> Self { - Self { _phantom: PhantomData } + Self { + _phantom: PhantomData, + max_subsequence_len: usize::MAX, + min_subsequence_len: 0, + } } } @@ -284,20 +290,31 @@ where type Chromosome = NodePermutation; fn perturb(&self, chromosome: &mut Self::Chromosome, rng: &mut dyn RngCore) { - let first = rng.random_range(0..chromosome.permutation.len()); - let second = rng.random_range(0..chromosome.permutation.len()); - - let start = first.min(second); - let end = first.max(second); + let len = chromosome.permutation.len(); + let index = rng.random_range(0..chromosome.permutation.len()); + let subsequence_len = rng.random_range( + self.min_subsequence_len..(chromosome.permutation.len().min(self.max_subsequence_len)) + ); // Reverse the subsequence between start and end (inclusive) - let mut left = start; - let mut right = end; + let mut left = index; + let mut right = (index + subsequence_len) % len; - while left < right { + while left != right { chromosome.permutation.swap_rows(left, right); + left += 1; - right -= 1; + left %= len; + + if left == right { + break; + } + + if right > 0 { + right -= 1; + } else { + right = len - 1; + } } } }