Function utils::graph::explore_hamiltonian_paths
source · pub fn explore_hamiltonian_paths<E, P: Copy>(
vertices: u32,
start_vertex: u32,
initial_path: P,
distance_fn: impl Fn(u32, u32) -> E,
accumulate_fn: impl Fn(P, E) -> P,
callback_fn: impl FnMut(P, E),
)
Expand description
Explore all hamiltonian paths/cycles in a graph.
§Panics
This function panics if the number of vertices exceeds the maximum supported, currently 32.
§Examples
Shortest hamiltonian path and cycle starting at vertex 0:
let distance_matrix = vec![
0, 7, 2, 8, 6,
7, 0, 1, 3, 5,
2, 1, 0, 9, 4,
8, 3, 9, 0, 9,
6, 5, 4, 9, 0,
];
let mut min_hamiltonian_path = u32::MAX;
let mut min_hamiltonian_cycle = u32::MAX;
explore_hamiltonian_paths(
5, // Number of vertices
0, // Start vertex
0, // Initial path cost
|a, b| distance_matrix[a as usize * 5 + b as usize], // Distance function
u32::add, // Accumulate function
|path, loop_edge| { // Callback function
min_hamiltonian_path = min_hamiltonian_path.min(path);
min_hamiltonian_cycle = min_hamiltonian_cycle.min(path + loop_edge);
}
);
assert_eq!(min_hamiltonian_path, 14); // 0 =[6]=> 4 =[4]=> 2 =[1]=> 1 =[3]=> 3
assert_eq!(min_hamiltonian_cycle, 21); // 0 =[2]=> 2 =[1]=> 1 =[3]=> 3 =[9]=> 4 =[6]=> 0
Shortest and longest hamilton paths starting at any vertex:
let distance_matrix = vec![
0, 7, 2, 8, 6,
7, 0, 1, 3, 5,
2, 1, 0, 9, 4,
8, 3, 9, 0, 9,
6, 5, 4, 9, 0,
];
let mut min_path = u32::MAX;
let mut max_path = 0;
explore_hamiltonian_paths(
5, // Number of vertices
0, // Start vertex
(0, u32::MAX, 0), // Initial path cost
|a, b| distance_matrix[a as usize * 5 + b as usize], // Distance function
|(total, min_edge, max_edge), edge| { // Accumulate function
(total + edge, min_edge.min(edge), max_edge.max(edge))
},
|(total, min_edge, max_edge), loop_edge| { // Callback function
let loop_total = total + loop_edge;
min_path = min_path.min(loop_total - max_edge.max(loop_edge));
max_path = max_path.max(loop_total - min_edge.min(loop_edge));
}
);
assert_eq!(min_path, 12); // 3 =[3]=> 1 =[1]=> 2 =[2]=> 0 =[6]=> 4
assert_eq!(max_path, 31); // 1 =[7]=> 0 =[6]=> 4 =[9]=> 3 =[9]=> 2