Skip to content

Commit f99c5aa

Browse files
committed
Merge branch 'issue-9-cvrp-tests-r060-stack' into release/0.6.0
2 parents 955b090 + 5e6b7e3 commit f99c5aa

File tree

1 file changed

+124
-0
lines changed
  • crates/solverforge-cvrp/src

1 file changed

+124
-0
lines changed

crates/solverforge-cvrp/src/lib.rs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,127 @@ impl<S: VrpSolution> CrossEntityDistanceMeter<S> for MatrixIntraDistanceMeter {
203203
data.distance_matrix[visits[src_pos]][visits[dst_pos]] as f64
204204
}
205205
}
206+
207+
#[cfg(test)]
208+
mod tests {
209+
use super::*;
210+
211+
struct TestSolution {
212+
data: Box<ProblemData>,
213+
routes: Vec<Vec<usize>>,
214+
}
215+
216+
impl TestSolution {
217+
fn new(routes: Vec<Vec<usize>>) -> Self {
218+
Self {
219+
data: Box::new(ProblemData {
220+
capacity: 10,
221+
depot: 0,
222+
demands: vec![0, 2, 3, 4],
223+
distance_matrix: vec![
224+
vec![0, 5, 7, 9],
225+
vec![5, 0, 4, 6],
226+
vec![7, 4, 0, 3],
227+
vec![9, 6, 3, 0],
228+
],
229+
time_windows: vec![(0, 100), (0, 10), (7, 14), (0, 12)],
230+
service_durations: vec![0, 2, 2, 3],
231+
travel_times: vec![
232+
vec![0, 5, 7, 9],
233+
vec![5, 0, 4, 6],
234+
vec![7, 4, 0, 3],
235+
vec![9, 6, 3, 0],
236+
],
237+
vehicle_departure_time: 0,
238+
}),
239+
routes,
240+
}
241+
}
242+
}
243+
244+
impl VrpSolution for TestSolution {
245+
fn vehicle_data_ptr(&self, _entity_idx: usize) -> *const ProblemData {
246+
self.data.as_ref() as *const ProblemData
247+
}
248+
249+
fn vehicle_visits(&self, entity_idx: usize) -> &[usize] {
250+
&self.routes[entity_idx]
251+
}
252+
253+
fn vehicle_visits_mut(&mut self, entity_idx: usize) -> &mut Vec<usize> {
254+
&mut self.routes[entity_idx]
255+
}
256+
257+
fn vehicle_count(&self) -> usize {
258+
self.routes.len()
259+
}
260+
}
261+
262+
#[test]
263+
fn helpers_use_problem_data_from_first_vehicle() {
264+
let solution = TestSolution::new(vec![vec![1, 2], vec![3]]);
265+
266+
assert_eq!(distance(&solution, 1, 3), 6);
267+
assert_eq!(depot_for_entity(&solution, 1), 0);
268+
assert_eq!(depot_for_cw(&solution), 0);
269+
assert_eq!(element_load(&solution, 2), 3);
270+
assert_eq!(capacity(&solution), 10);
271+
}
272+
273+
#[test]
274+
fn helpers_handle_empty_fleets() {
275+
let solution = TestSolution::new(vec![]);
276+
277+
assert_eq!(distance(&solution, 1, 2), 0);
278+
assert_eq!(depot_for_entity(&solution, 0), 0);
279+
assert_eq!(depot_for_cw(&solution), 0);
280+
assert_eq!(element_load(&solution, 1), 0);
281+
assert_eq!(capacity(&solution), i64::MAX);
282+
assert!(is_time_feasible(&solution, &[1, 2]));
283+
assert!(is_kopt_feasible(&solution, 0, &[1, 2]));
284+
}
285+
286+
#[test]
287+
fn route_helpers_replace_and_clone_routes() {
288+
let mut solution = TestSolution::new(vec![vec![1, 2], vec![3]]);
289+
290+
assign_route(&mut solution, 0, vec![2, 3]);
291+
assert_eq!(solution.routes[0], vec![2, 3]);
292+
assert_eq!(get_route(&solution, 0), vec![2, 3]);
293+
294+
set_route(&mut solution, 1, vec![1]);
295+
assert_eq!(solution.routes[1], vec![1]);
296+
}
297+
298+
#[test]
299+
fn time_feasibility_checks_waiting_and_deadlines() {
300+
let solution = TestSolution::new(vec![vec![1, 2], vec![3]]);
301+
302+
assert!(
303+
is_time_feasible(&solution, &[1, 2]),
304+
"route should wait for customer 2 and still finish in time"
305+
);
306+
assert!(
307+
!is_time_feasible(&solution, &[2, 3]),
308+
"route should miss customer 3's latest end"
309+
);
310+
assert!(is_kopt_feasible(&solution, 1, &[1, 2]));
311+
}
312+
313+
#[test]
314+
fn distance_meters_cover_invalid_positions() {
315+
let solution = TestSolution::new(vec![vec![1, 2], vec![3]]);
316+
317+
assert_eq!(MatrixDistanceMeter.distance(&solution, 0, 0, 1, 0), 6.0);
318+
assert_eq!(
319+
MatrixIntraDistanceMeter.distance(&solution, 0, 0, 0, 1),
320+
4.0
321+
);
322+
assert!(MatrixDistanceMeter
323+
.distance(&solution, 0, 4, 1, 0)
324+
.is_infinite());
325+
assert!(MatrixIntraDistanceMeter
326+
.distance(&solution, 0, 0, 0, 4)
327+
.is_infinite());
328+
}
329+
}

0 commit comments

Comments
 (0)