Skip to main content

ListCheapestInsertionPhase

Struct ListCheapestInsertionPhase 

Source
pub struct ListCheapestInsertionPhase<S, E>
where S: PlanningSolution, E: Copy + PartialEq + Eq + Hash + Send + Sync + 'static,
{ /* private fields */ }
Expand description

List construction phase using greedy cheapest insertion.

For each unassigned element (in index order), evaluates all possible insertion positions across all entities and inserts it at the position that yields the best score. This is significantly better than round-robin for VRP because:

  • Routes are built incrementally with score feedback
  • Capacity constraints influence which vehicle receives each visit
  • Distance/duration constraints are optimized at the point of insertion

§Algorithm

for each unassigned element e:
    for each entity r and each position p in r:
        try insert(e, r, p), score, undo
    permanently insert e at (r*, p*) with best score

Complexity: O(E × N × M) where E = elements, N = entities, M = avg route length.

§Example

use solverforge_solver::ListCheapestInsertionPhase;
use solverforge_core::domain::PlanningSolution;
use solverforge_core::score::SimpleScore;

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

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

impl PlanningSolution for Plan {
    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: &Plan, e: usize) -> usize {
    s.vehicles.get(e).map_or(0, |v| v.visits.len())
}
fn list_insert(s: &mut Plan, e: usize, pos: usize, val: usize) {
    if let Some(v) = s.vehicles.get_mut(e) { v.visits.insert(pos, val); }
}
fn list_remove(s: &mut Plan, e: usize, pos: usize) -> usize {
    s.vehicles.get_mut(e).map(|v| v.visits.remove(pos)).unwrap_or(0)
}

let phase = ListCheapestInsertionPhase::<Plan, usize>::new(
    |p| p.n_visits,
    |p| p.vehicles.iter().flat_map(|v| v.visits.iter().copied()).collect(),
    |p| p.vehicles.len(),
    list_len,
    list_insert,
    list_remove,
    |idx| idx,
    "visits",
    0,
);

Implementations§

Source§

impl<S, E> ListCheapestInsertionPhase<S, E>
where S: PlanningSolution, E: Copy + PartialEq + Eq + Hash + Send + Sync + 'static,

Source

pub fn new( element_count: fn(&S) -> usize, get_assigned: fn(&S) -> Vec<E>, entity_count: fn(&S) -> usize, list_len: fn(&S, usize) -> usize, list_insert: fn(&mut S, usize, usize, E), list_remove: fn(&mut S, usize, usize) -> E, index_to_element: fn(usize) -> E, variable_name: &'static str, descriptor_index: usize, ) -> Self

Creates a new cheapest insertion phase.

§Arguments
  • element_count - Total number of elements to assign
  • get_assigned - Returns currently assigned elements
  • entity_count - Total number of entities (routes/vehicles)
  • list_len - Length of entity’s list
  • list_insert - Insert element at position (shifts right)
  • list_remove - Remove element at position (used for undo), returns removed element
  • index_to_element - Converts element index to element value
  • variable_name - Name of the list variable
  • descriptor_index - Entity descriptor index

Trait Implementations§

Source§

impl<S, E> Debug for ListCheapestInsertionPhase<S, E>
where S: PlanningSolution, E: Copy + PartialEq + Eq + Hash + Send + Sync + 'static,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<S, E, D> Phase<S, D> for ListCheapestInsertionPhase<S, E>
where S: PlanningSolution, E: Copy + PartialEq + Eq + Hash + Send + Sync + 'static, D: ScoreDirector<S>,

Source§

fn solve(&mut self, solver_scope: &mut SolverScope<'_, S, D>)

Executes this phase. Read more
Source§

fn phase_type_name(&self) -> &'static str

Returns the name of this phase type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more