This commit is contained in:
Zynh0722 2024-04-25 19:28:41 -07:00
parent ba5642063e
commit 6568a0056f

View file

@ -184,8 +184,10 @@ fn main() -> Result<(), Box<dyn Error>> {
let origin = graph[&origin_id].clone(); let origin = graph[&origin_id].clone();
let destination = graph[&destination_id].clone(); let destination = graph[&destination_id].clone();
// Set starting node distance to 0
origin.deref().borrow_mut().source_distance = NonNan(0.0); origin.deref().borrow_mut().source_distance = NonNan(0.0);
// Populate unvisted set
#[allow(clippy::mutable_key_type)] #[allow(clippy::mutable_key_type)]
let mut unvisited: BTreeSet<NodePointer> = BTreeSet::new(); let mut unvisited: BTreeSet<NodePointer> = BTreeSet::new();
@ -193,34 +195,46 @@ fn main() -> Result<(), Box<dyn Error>> {
unvisited.insert(node.clone()); unvisited.insert(node.clone());
} }
// Begin Dijkstraing
while let Some(current_node) = unvisited.pop_first() { while let Some(current_node) = unvisited.pop_first() {
// If at destination, we're done
if current_node.borrow().deref() == destination.borrow().deref() { if current_node.borrow().deref() == destination.borrow().deref() {
break; break;
} }
// Iterate over neighbors of current node
for target in &current_node.borrow().destinations { for target in &current_node.borrow().destinations {
// Calculate source distance
let new_distance = current_node.borrow().source_distance.0 + target.distance; let new_distance = current_node.borrow().source_distance.0 + target.distance;
// If new distance is smaller, update the node
if new_distance < target.node.borrow().source_distance.0 { if new_distance < target.node.borrow().source_distance.0 {
// Remove from set (necessary to keep the BTreeSet invariant true)
let destination_node = unvisited.take(&target.node).unwrap(); let destination_node = unvisited.take(&target.node).unwrap();
// Update the source distance
{ {
let mut node_ref = destination_node.deref().borrow_mut(); let mut node_ref = destination_node.deref().borrow_mut();
node_ref.previous_node = Some(current_node.clone()); node_ref.previous_node = Some(current_node.clone());
node_ref.source_distance = NonNan(new_distance); node_ref.source_distance = NonNan(new_distance);
} }
// Reinsert the node to sort it back into the set
unvisited.insert(destination_node); unvisited.insert(destination_node);
} }
} }
} }
// A little iterator that helps reconstruct the path
let follower = PathFollower { let follower = PathFollower {
next_node: Some(destination.clone()), next_node: Some(destination.clone()),
}; };
// Flip the path, as it is stored as previous_node in the node struct
let reversed_path: Vec<NodePointer> = follower.collect(); let reversed_path: Vec<NodePointer> = follower.collect();
let path: Vec<NodePointer> = reversed_path.into_iter().rev().collect(); let path: Vec<NodePointer> = reversed_path.into_iter().rev().collect();
// If path was found, print output, else state no path found
if path.len() > 1 { if path.len() > 1 {
println!( println!(
"Total Distance: {}", "Total Distance: {}",