diff --git a/src/algorithms.rs b/src/algorithms.rs index a5016ce..375e46c 100644 --- a/src/algorithms.rs +++ b/src/algorithms.rs @@ -1,6 +1,7 @@ use std::cmp::Ordering; use std::collections::BinaryHeap; +use crate::maps::VertexMap; use crate::traits::GraphTopology; #[derive(PartialEq, Eq)] @@ -21,19 +22,18 @@ impl Ord for DistanceOrderedVertex { } } -pub struct DijkstraResult { - pub distances: Vec>, - pub predecessors: Vec>, +pub struct DijkstraResult { + pub distances: VertexMap>, + pub predecessors: VertexMap>, } pub fn dijkstra(graph: &G, source: G::Vertex) -> DijkstraResult where G: GraphTopology, - G::Vertex: Into, { - let mut predecessors = vec![None; graph.vertex_count()]; + let mut predecessors = graph.vertex_map(None); let distances = dijkstra_impl(graph, source, |neighbor, predecessor| { - predecessors[neighbor.into()] = Some(predecessor); + predecessors[neighbor] = Some(predecessor); }); DijkstraResult { distances, @@ -41,25 +41,27 @@ where } } -pub fn dijkstra_distances(graph: &G, source: G::Vertex) -> Vec> +pub fn dijkstra_distances(graph: &G, source: G::Vertex) -> VertexMap> where G: GraphTopology, - G::Vertex: Into, { dijkstra_impl(graph, source, |_, _| {}) } -// TODO: Replace Vec storage with VertexMap, this should make the bound on G::Vertex here obsolete. -fn dijkstra_impl(graph: &G, source: G::Vertex, mut on_relax: F) -> Vec> +// TODO: Add a way to provide custom edge weights for Dijkstra's algorithm. +fn dijkstra_impl( + graph: &G, + source: G::Vertex, + mut on_relax: F, +) -> VertexMap> where G: GraphTopology, - G::Vertex: Into, F: FnMut(G::Vertex, G::Vertex), { - let mut distances = vec![None; graph.vertex_count()]; + let mut distances = graph.vertex_map(None); let mut heap = BinaryHeap::new(); - distances[source.into()] = Some(0); + distances[source] = Some(0); heap.push(DistanceOrderedVertex { vertex: source, distance: 0, @@ -67,15 +69,14 @@ where while let Some(v) = heap.pop() { for neighbor in graph.neighbors(v.vertex) { - // TODO: Add a way to provide custom edge weights for Dijkstra's algorithm. let edge_weight = 1; - let new_distance = distances[v.vertex.into()].unwrap() + edge_weight; - if match distances[neighbor.into()] { + let new_distance = distances[v.vertex].unwrap() + edge_weight; + if match distances[neighbor] { None => true, Some(old_distance) if old_distance > new_distance => true, _ => false, } { - distances[neighbor.into()] = Some(new_distance); + distances[neighbor] = Some(new_distance); on_relax(neighbor, v.vertex); heap.push(DistanceOrderedVertex { vertex: neighbor,