Skip to main content

Module sublist_swap

Module sublist_swap 

Source
Expand description

Sublist swap move selector for segment exchange.

Generates SubListSwapMoves that swap contiguous segments within or between list variables. Useful for balanced inter-route segment exchanges in VRP.

§Complexity

For n entities with average route length m and max segment size k:

  • Intra-entity pairs: O(n * m² * k²) — triangular over non-overlapping segments
  • Inter-entity pairs: O(n² * m² * k²) — all pairs across entities

Use a forager that quits early for large instances.

§Example

use solverforge_solver::heuristic::selector::sublist_swap::SubListSwapMoveSelector;
use solverforge_solver::heuristic::selector::entity::FromSolutionEntitySelector;
use solverforge_solver::heuristic::selector::MoveSelector;
use solverforge_core::domain::PlanningSolution;
use solverforge_core::score::SimpleScore;

#[derive(Clone, Debug)]
struct Vehicle { visits: Vec<i32> }

#[derive(Clone, Debug)]
struct Solution { vehicles: Vec<Vehicle>, score: Option<SimpleScore> }

impl PlanningSolution for Solution {
    type Score = SimpleScore;
    fn score(&self) -> Option<Self::Score> { self.score }
    fn set_score(&mut self, score: Option<Self::Score>) { self.score = score; }
}

fn list_len(s: &Solution, entity_idx: usize) -> usize {
    s.vehicles.get(entity_idx).map_or(0, |v| v.visits.len())
}
fn sublist_remove(s: &mut Solution, entity_idx: usize, start: usize, end: usize) -> Vec<i32> {
    s.vehicles.get_mut(entity_idx)
        .map(|v| v.visits.drain(start..end).collect())
        .unwrap_or_default()
}
fn sublist_insert(s: &mut Solution, entity_idx: usize, pos: usize, items: Vec<i32>) {
    if let Some(v) = s.vehicles.get_mut(entity_idx) {
        for (i, item) in items.into_iter().enumerate() {
            v.visits.insert(pos + i, item);
        }
    }
}

// Swap segments of size 1..=3 between routes
let selector = SubListSwapMoveSelector::<Solution, i32, _>::new(
    FromSolutionEntitySelector::new(0),
    1, 3,
    list_len,
    sublist_remove,
    sublist_insert,
    "visits",
    0,
);

Structs§

ListMoveSubListSwapSelector
Wraps a SubListSwapMoveSelector to yield ListMoveImpl::SubListSwap.
SubListSwapMoveSelector
A move selector that generates sublist swap moves.