Skip to main content

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::SoftScore;

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

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

impl PlanningSolution for VrpSolution {
    type Score = SoftScore;
    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§

Required Methods§

Source

fn entity_count(&self) -> usize

Source

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

Source

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

Source

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

Source

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

Source

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

Source

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

Source

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

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§