use pie_core::FibHeap;
use std::collections::HashMap;
type Graph = HashMap<char, Vec<(char, u32)>>;
fn create_graph() -> Graph {
let mut graph = Graph::new();
graph.insert('A', vec![('B', 10), ('C', 3)]);
graph.insert('B', vec![('D', 2)]);
graph.insert('C', vec![('B', 4), ('D', 8), ('E', 2)]);
graph.insert('D', vec![('E', 5)]);
graph.insert('E', vec![]);
graph
}
fn visualize_graph(graph: &Graph) -> String {
let mut output = String::from("Graph Structure:\n");
let mut nodes: Vec<_> = graph.keys().collect();
nodes.sort();
for node in nodes {
let neighbors = graph.get(node).unwrap();
let neighbors_str: Vec<String> = neighbors.iter()
.map(|(n, w)| format!("({}, {})", n, w))
.collect();
output.push_str(&format!(" {} -> [ {} ]\n", node, neighbors_str.join(", ")));
}
output
}
#[test]
fn real_world_pathfinding_test() {
println!("--- Test Start: Dijkstra's Pathfinding ---");
let mut heap = FibHeap::new();
let graph = create_graph();
let start_node = 'A';
let nodes = ['A', 'B', 'C', 'D', 'E'];
println!("{}", visualize_graph(&graph));
println!("Starting node: {start_node}");
let mut distances = HashMap::new();
let mut handles = HashMap::new();
println!("Populating heap with initial distances...");
for &node in &nodes {
let dist = if node == start_node { 0 } else { u32::MAX };
distances.insert(node, dist);
let handle = heap.push(dist, node);
handles.insert(node, handle);
println!("Pushed: ('{}', prio: {})", node, dist);
}
assert_eq!(heap.len(), nodes.len());
while let Some((current_dist, current_node)) = heap.pop() {
println!("\n--- Popped node '{}' with dist {} ---", current_node, current_dist);
if current_dist == u32::MAX {
println!("Node is unreachable. Stopping.");
break;
}
if let Some(neighbors) = graph.get(¤t_node) {
for &(neighbor, weight) in neighbors {
let new_dist = current_dist + weight;
if new_dist < distances[&neighbor] {
println!("Found shorter path to '{}': {} < {}", neighbor, new_dist, distances[&neighbor]);
distances.insert(neighbor, new_dist);
let neighbor_handle = handles[&neighbor];
heap.decrease_key(neighbor_handle, new_dist).unwrap();
println!("Updated heap: ('{}', prio: {})", neighbor, new_dist);
}
}
}
}
assert_eq!(heap.len(), 0);
println!("\n--- Final Shortest Distances from '{}' ---", start_node);
println!("Node A: {}", distances[&'A']); println!("Node B: {}", distances[&'B']); println!("Node C: {}", distances[&'C']); println!("Node D: {}", distances[&'D']); println!("Node E: {}", distances[&'E']); assert_eq!(distances[&'A'], 0);
assert_eq!(distances[&'B'], 7);
assert_eq!(distances[&'C'], 3);
assert_eq!(distances[&'D'], 9);
assert_eq!(distances[&'E'], 5);
println!("--- Test Complete ---");
}