~ruther/ctu-fee-eoa

e3d7f2139691f8df389f621703c3a7827d765fbf — Rutherther a month ago 4d86e22
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.
1 files changed, 28 insertions(+), 11 deletions(-)

M codes/tsp_hw01/src/tsp.rs
M codes/tsp_hw01/src/tsp.rs => codes/tsp_hw01/src/tsp.rs +28 -11
@@ 266,12 266,18 @@ where
}

pub struct ReverseSubsequencePerturbation<D> {
    _phantom: PhantomData<D>
    _phantom: PhantomData<D>,
    min_subsequence_len: usize,
    max_subsequence_len: usize,
}

impl<D> ReverseSubsequencePerturbation<D> {
    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<D>;

    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;
            }
        }
    }
}