Skip to main content

solverforge_cvrp/
meters.rs

1use solverforge_solver::CrossEntityDistanceMeter;
2
3use crate::helpers::problem_data_for_entity;
4use crate::VrpSolution;
5
6// Cross-entity distance meter backed by the solution's distance matrix.
7#[derive(Clone, Debug, Default)]
8pub struct MatrixDistanceMeter;
9
10impl<S: VrpSolution> CrossEntityDistanceMeter<S> for MatrixDistanceMeter {
11    fn distance(
12        &self,
13        solution: &S,
14        src_entity: usize,
15        src_pos: usize,
16        dst_entity: usize,
17        dst_pos: usize,
18    ) -> f64 {
19        let src_visits = solution.vehicle_visits(src_entity);
20        let dst_visits = solution.vehicle_visits(dst_entity);
21        if src_pos >= src_visits.len() || dst_pos >= dst_visits.len() {
22            return f64::INFINITY;
23        }
24        problem_data_for_entity(solution, src_entity)
25            .and_then(|data| data.finite_distance(src_visits[src_pos], dst_visits[dst_pos]))
26            .map_or(f64::INFINITY, |distance| distance as f64)
27    }
28}
29
30// Intra-entity distance meter backed by the solution's distance matrix.
31#[derive(Clone, Debug, Default)]
32pub struct MatrixIntraDistanceMeter;
33
34impl<S: VrpSolution> CrossEntityDistanceMeter<S> for MatrixIntraDistanceMeter {
35    fn distance(
36        &self,
37        solution: &S,
38        src_entity: usize,
39        src_pos: usize,
40        _dst_entity: usize,
41        dst_pos: usize,
42    ) -> f64 {
43        let visits = solution.vehicle_visits(src_entity);
44        if src_pos >= visits.len() || dst_pos >= visits.len() {
45            return f64::INFINITY;
46        }
47        problem_data_for_entity(solution, src_entity)
48            .and_then(|data| data.finite_distance(visits[src_pos], visits[dst_pos]))
49            .map_or(f64::INFINITY, |distance| distance as f64)
50    }
51}