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 ListVariableContext<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 ListVariableContext<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> ListVariableContext<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 ListVariableContext<S, V, DM, IDM> {
168 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169 f.debug_struct("ListVariableContext")
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}