ListVariableSolution

Trait ListVariableSolution 

Source
pub trait ListVariableSolution: PlanningSolution {
    type Element: Copy + Send + Sync;

    // Required methods
    fn entity_count(&self) -> usize;
    fn list_len(&self, entity_idx: usize) -> usize;
    fn list_get(&self, entity_idx: usize, position: usize) -> Self::Element;
    fn list_push(&mut self, entity_idx: usize, elem: Self::Element);
    fn list_insert(
        &mut self,
        entity_idx: usize,
        position: usize,
        elem: Self::Element,
    );
    fn list_remove(
        &mut self,
        entity_idx: usize,
        position: usize,
    ) -> Self::Element;
    fn list_reverse(&mut self, entity_idx: usize, start: usize, end: usize);
    fn unassigned_elements(&self) -> Vec<Self::Element>;
}
Expand description

Trait for solutions with list-based planning variables.

Used for problems like VRP where entities (vehicles) have ordered lists of elements (visits) that can be inserted, removed, or reordered.

§Examples

use solverforge_core::domain::ListVariableSolution;
use solverforge_core::PlanningSolution;
use solverforge_core::score::SimpleScore;

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

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

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

impl ListVariableSolution for VrpSolution {
    type Element = usize;

    fn entity_count(&self) -> usize {
        self.vehicles.len()
    }

    fn list_len(&self, entity_idx: usize) -> usize {
        self.vehicles[entity_idx].visits.len()
    }

    fn list_get(&self, entity_idx: usize, position: usize) -> Self::Element {
        self.vehicles[entity_idx].visits[position]
    }

    fn list_push(&mut self, entity_idx: usize, elem: Self::Element) {
        self.vehicles[entity_idx].visits.push(elem);
    }

    fn list_insert(&mut self, entity_idx: usize, position: usize, elem: Self::Element) {
        self.vehicles[entity_idx].visits.insert(position, elem);
    }

    fn list_remove(&mut self, entity_idx: usize, position: usize) -> Self::Element {
        self.vehicles[entity_idx].visits.remove(position)
    }

    fn list_reverse(&mut self, entity_idx: usize, start: usize, end: usize) {
        self.vehicles[entity_idx].visits[start..end].reverse();
    }

    fn unassigned_elements(&self) -> Vec<Self::Element> {
        use std::collections::HashSet;
        let assigned: HashSet<usize> = self.vehicles
            .iter()
            .flat_map(|v| v.visits.iter().copied())
            .collect();
        (0..self.visit_count)
            .filter(|i| !assigned.contains(i))
            .collect()
    }
}

Required Associated Types§

Source

type Element: Copy + Send + Sync

The type of elements in the list (typically an index or ID).

Required Methods§

Source

fn entity_count(&self) -> usize

Returns the number of entities (list owners).

Source

fn list_len(&self, entity_idx: usize) -> usize

Returns the length of the list for the given entity.

Source

fn list_get(&self, entity_idx: usize, position: usize) -> Self::Element

Returns the element at the given position in the entity’s list.

Source

fn list_push(&mut self, entity_idx: usize, elem: Self::Element)

Appends an element to the end of the entity’s list.

Source

fn list_insert( &mut self, entity_idx: usize, position: usize, elem: Self::Element, )

Inserts an element at the given position in the entity’s list.

Source

fn list_remove(&mut self, entity_idx: usize, position: usize) -> Self::Element

Removes and returns the element at the given position.

Source

fn list_reverse(&mut self, entity_idx: usize, start: usize, end: usize)

Reverses the elements in the range [start, end) for the entity’s list.

Source

fn unassigned_elements(&self) -> Vec<Self::Element>

Returns all elements not currently assigned to any entity.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§