From 01683735094b398bb279145eff11a28f80385e11 Mon Sep 17 00:00:00 2001 From: Joscha Date: Tue, 31 Dec 2024 11:26:32 +0100 Subject: [PATCH] Move dijkstra to new file --- brood/src/algo.rs | 78 +------------------------------------- brood/src/algo/dijkstra.rs | 77 +++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 76 deletions(-) create mode 100644 brood/src/algo/dijkstra.rs diff --git a/brood/src/algo.rs b/brood/src/algo.rs index b6bf26a..ffc1aa5 100644 --- a/brood/src/algo.rs +++ b/brood/src/algo.rs @@ -1,77 +1,3 @@ -use std::{cmp::Reverse, collections::BinaryHeap}; +mod dijkstra; -use crate::graph::{EdgeIdx, Graph, NodeIdx}; - -pub struct Dijkstra<'a> { - graph: &'a Graph, - cost: Vec, - pred: Vec, -} - -impl<'a> Dijkstra<'a> { - pub fn new(graph: &'a Graph) -> Self { - Self { - graph, - cost: vec![u32::MAX; graph.nodes.len()], - pred: vec![NodeIdx::NONE; graph.nodes.len()], - } - } - - pub fn run( - &mut self, - start: NodeIdx, - goal: impl Fn(NodeIdx) -> bool, - cost: impl Fn(NodeIdx, EdgeIdx, NodeIdx) -> u32, - ) { - self.cost[start.usize()] = 0; - let mut queue = BinaryHeap::new(); - queue.push((Reverse(0), start)); - - while let Some((Reverse(curr_cost), curr)) = queue.pop() { - if goal(curr) { - break; // We've found the shortest path to our target - } - - // These seem to never actually occur - // if curr_cost > self.cost[curr.usize()] { - // continue; // Outdated entry - // } - - for edge in self.graph.edge_range(curr).map(EdgeIdx::new) { - let next = self.graph.edges[edge.usize()]; - let next_cost = curr_cost + cost(curr, edge, next); - if next_cost < self.cost[next.usize()] { - self.cost[next.usize()] = next_cost; - self.pred[next.usize()] = curr; - queue.push((Reverse(next_cost), next)); - } - } - } - } - - #[inline] - pub fn cost(&self, node: NodeIdx) -> u32 { - self.cost[node.usize()] - } - - #[inline] - pub fn pred(&self, node: NodeIdx) -> NodeIdx { - self.pred[node.usize()] - } - - pub fn path(&self, goal: NodeIdx) -> Vec { - let mut path = vec![]; - let mut at = goal; - - loop { - path.push(at); - at = self.pred(at); - if at == NodeIdx::NONE { - break; - } - } - - path.reverse(); - path - } -} +pub use self::dijkstra::*; diff --git a/brood/src/algo/dijkstra.rs b/brood/src/algo/dijkstra.rs new file mode 100644 index 0000000..b6bf26a --- /dev/null +++ b/brood/src/algo/dijkstra.rs @@ -0,0 +1,77 @@ +use std::{cmp::Reverse, collections::BinaryHeap}; + +use crate::graph::{EdgeIdx, Graph, NodeIdx}; + +pub struct Dijkstra<'a> { + graph: &'a Graph, + cost: Vec, + pred: Vec, +} + +impl<'a> Dijkstra<'a> { + pub fn new(graph: &'a Graph) -> Self { + Self { + graph, + cost: vec![u32::MAX; graph.nodes.len()], + pred: vec![NodeIdx::NONE; graph.nodes.len()], + } + } + + pub fn run( + &mut self, + start: NodeIdx, + goal: impl Fn(NodeIdx) -> bool, + cost: impl Fn(NodeIdx, EdgeIdx, NodeIdx) -> u32, + ) { + self.cost[start.usize()] = 0; + let mut queue = BinaryHeap::new(); + queue.push((Reverse(0), start)); + + while let Some((Reverse(curr_cost), curr)) = queue.pop() { + if goal(curr) { + break; // We've found the shortest path to our target + } + + // These seem to never actually occur + // if curr_cost > self.cost[curr.usize()] { + // continue; // Outdated entry + // } + + for edge in self.graph.edge_range(curr).map(EdgeIdx::new) { + let next = self.graph.edges[edge.usize()]; + let next_cost = curr_cost + cost(curr, edge, next); + if next_cost < self.cost[next.usize()] { + self.cost[next.usize()] = next_cost; + self.pred[next.usize()] = curr; + queue.push((Reverse(next_cost), next)); + } + } + } + } + + #[inline] + pub fn cost(&self, node: NodeIdx) -> u32 { + self.cost[node.usize()] + } + + #[inline] + pub fn pred(&self, node: NodeIdx) -> NodeIdx { + self.pred[node.usize()] + } + + pub fn path(&self, goal: NodeIdx) -> Vec { + let mut path = vec![]; + let mut at = goal; + + loop { + path.push(at); + at = self.pred(at); + if at == NodeIdx::NONE { + break; + } + } + + path.reverse(); + path + } +}