Skip to main content

solverforge_solver/builder/context/
list.rs

1use std::fmt;
2use std::marker::PhantomData;
3
4use crate::heuristic::selector::k_opt::ListPositionDistanceMeter;
5use crate::heuristic::selector::nearby_list_change::CrossEntityDistanceMeter;
6
7pub struct IntraDistanceAdapter<T>(pub T);
8
9impl<S, T: CrossEntityDistanceMeter<S>> ListPositionDistanceMeter<S> for IntraDistanceAdapter<T> {
10    fn distance(&self, solution: &S, entity_idx: usize, pos_a: usize, pos_b: usize) -> f64 {
11        self.0
12            .distance(solution, entity_idx, pos_a, entity_idx, pos_b)
13    }
14}
15
16pub struct ListVariableSlot<S, V, DM, IDM> {
17    pub entity_type_name: &'static str,
18    pub element_count: fn(&S) -> usize,
19    pub assigned_elements: fn(&S) -> Vec<V>,
20    pub list_len: fn(&S, usize) -> usize,
21    pub list_remove: fn(&mut S, usize, usize) -> Option<V>,
22    pub construction_list_remove: fn(&mut S, usize, usize) -> V,
23    pub list_insert: fn(&mut S, usize, usize, V),
24    pub list_get: fn(&S, usize, usize) -> Option<V>,
25    pub list_set: fn(&mut S, usize, usize, V),
26    pub list_reverse: fn(&mut S, usize, usize, usize),
27    pub sublist_remove: fn(&mut S, usize, usize, usize) -> Vec<V>,
28    pub sublist_insert: fn(&mut S, usize, usize, Vec<V>),
29    pub ruin_remove: fn(&mut S, usize, usize) -> V,
30    pub ruin_insert: fn(&mut S, usize, usize, V),
31    pub index_to_element: fn(&S, usize) -> V,
32    pub entity_count: fn(&S) -> usize,
33    pub cross_distance_meter: DM,
34    pub intra_distance_meter: IDM,
35    pub variable_name: &'static str,
36    pub descriptor_index: usize,
37    pub merge_feasible_fn: Option<fn(&S, &[usize]) -> bool>,
38    pub cw_depot_fn: Option<fn(&S) -> usize>,
39    pub cw_distance_fn: Option<fn(&S, usize, usize) -> i64>,
40    pub cw_element_load_fn: Option<fn(&S, usize) -> i64>,
41    pub cw_capacity_fn: Option<fn(&S) -> i64>,
42    pub cw_assign_route_fn: Option<fn(&mut S, usize, Vec<V>)>,
43    pub k_opt_get_route: Option<fn(&S, usize) -> Vec<usize>>,
44    pub k_opt_set_route: Option<fn(&mut S, usize, Vec<usize>)>,
45    pub k_opt_depot_fn: Option<fn(&S, usize) -> usize>,
46    pub k_opt_distance_fn: Option<fn(&S, usize, usize) -> i64>,
47    pub k_opt_feasible_fn: Option<fn(&S, usize, &[usize]) -> bool>,
48    _phantom: PhantomData<(fn() -> S, fn() -> V)>,
49}
50
51impl<S, V, DM: Clone, IDM: Clone> Clone for ListVariableSlot<S, V, DM, IDM> {
52    fn clone(&self) -> Self {
53        Self {
54            entity_type_name: self.entity_type_name,
55            element_count: self.element_count,
56            assigned_elements: self.assigned_elements,
57            list_len: self.list_len,
58            list_remove: self.list_remove,
59            construction_list_remove: self.construction_list_remove,
60            list_insert: self.list_insert,
61            list_get: self.list_get,
62            list_set: self.list_set,
63            list_reverse: self.list_reverse,
64            sublist_remove: self.sublist_remove,
65            sublist_insert: self.sublist_insert,
66            ruin_remove: self.ruin_remove,
67            ruin_insert: self.ruin_insert,
68            index_to_element: self.index_to_element,
69            entity_count: self.entity_count,
70            cross_distance_meter: self.cross_distance_meter.clone(),
71            intra_distance_meter: self.intra_distance_meter.clone(),
72            variable_name: self.variable_name,
73            descriptor_index: self.descriptor_index,
74            merge_feasible_fn: self.merge_feasible_fn,
75            cw_depot_fn: self.cw_depot_fn,
76            cw_distance_fn: self.cw_distance_fn,
77            cw_element_load_fn: self.cw_element_load_fn,
78            cw_capacity_fn: self.cw_capacity_fn,
79            cw_assign_route_fn: self.cw_assign_route_fn,
80            k_opt_get_route: self.k_opt_get_route,
81            k_opt_set_route: self.k_opt_set_route,
82            k_opt_depot_fn: self.k_opt_depot_fn,
83            k_opt_distance_fn: self.k_opt_distance_fn,
84            k_opt_feasible_fn: self.k_opt_feasible_fn,
85            _phantom: PhantomData,
86        }
87    }
88}
89
90impl<S, V, DM, IDM> ListVariableSlot<S, V, DM, IDM> {
91    #[allow(clippy::too_many_arguments)]
92    pub fn new(
93        entity_type_name: &'static str,
94        element_count: fn(&S) -> usize,
95        assigned_elements: fn(&S) -> Vec<V>,
96        list_len: fn(&S, usize) -> usize,
97        list_remove: fn(&mut S, usize, usize) -> Option<V>,
98        construction_list_remove: fn(&mut S, usize, usize) -> V,
99        list_insert: fn(&mut S, usize, usize, V),
100        list_get: fn(&S, usize, usize) -> Option<V>,
101        list_set: fn(&mut S, usize, usize, V),
102        list_reverse: fn(&mut S, usize, usize, usize),
103        sublist_remove: fn(&mut S, usize, usize, usize) -> Vec<V>,
104        sublist_insert: fn(&mut S, usize, usize, Vec<V>),
105        ruin_remove: fn(&mut S, usize, usize) -> V,
106        ruin_insert: fn(&mut S, usize, usize, V),
107        index_to_element: fn(&S, usize) -> V,
108        entity_count: fn(&S) -> usize,
109        cross_distance_meter: DM,
110        intra_distance_meter: IDM,
111        variable_name: &'static str,
112        descriptor_index: usize,
113        merge_feasible_fn: Option<fn(&S, &[usize]) -> bool>,
114        cw_depot_fn: Option<fn(&S) -> usize>,
115        cw_distance_fn: Option<fn(&S, usize, usize) -> i64>,
116        cw_element_load_fn: Option<fn(&S, usize) -> i64>,
117        cw_capacity_fn: Option<fn(&S) -> i64>,
118        cw_assign_route_fn: Option<fn(&mut S, usize, Vec<V>)>,
119        k_opt_get_route: Option<fn(&S, usize) -> Vec<usize>>,
120        k_opt_set_route: Option<fn(&mut S, usize, Vec<usize>)>,
121        k_opt_depot_fn: Option<fn(&S, usize) -> usize>,
122        k_opt_distance_fn: Option<fn(&S, usize, usize) -> i64>,
123        k_opt_feasible_fn: Option<fn(&S, usize, &[usize]) -> bool>,
124    ) -> Self {
125        Self {
126            entity_type_name,
127            element_count,
128            assigned_elements,
129            list_len,
130            list_remove,
131            construction_list_remove,
132            list_insert,
133            list_get,
134            list_set,
135            list_reverse,
136            sublist_remove,
137            sublist_insert,
138            ruin_remove,
139            ruin_insert,
140            index_to_element,
141            entity_count,
142            cross_distance_meter,
143            intra_distance_meter,
144            variable_name,
145            descriptor_index,
146            merge_feasible_fn,
147            cw_depot_fn,
148            cw_distance_fn,
149            cw_element_load_fn,
150            cw_capacity_fn,
151            cw_assign_route_fn,
152            k_opt_get_route,
153            k_opt_set_route,
154            k_opt_depot_fn,
155            k_opt_distance_fn,
156            k_opt_feasible_fn,
157            _phantom: PhantomData,
158        }
159    }
160
161    pub fn matches_target(&self, entity_class: Option<&str>, variable_name: Option<&str>) -> bool {
162        entity_class.is_none_or(|name| name == self.entity_type_name)
163            && variable_name.is_none_or(|name| name == self.variable_name)
164    }
165}
166
167impl<S, V, DM: fmt::Debug, IDM: fmt::Debug> fmt::Debug for ListVariableSlot<S, V, DM, IDM> {
168    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169        f.debug_struct("ListVariableSlot")
170            .field("entity_type_name", &self.entity_type_name)
171            .field("variable_name", &self.variable_name)
172            .field("descriptor_index", &self.descriptor_index)
173            .finish()
174    }
175}