diff --git a/src/algorithms.rs b/src/algorithms.rs index 375e46c..dc40241 100644 --- a/src/algorithms.rs +++ b/src/algorithms.rs @@ -27,12 +27,13 @@ pub struct DijkstraResult { pub predecessors: VertexMap>, } -pub fn dijkstra(graph: &G, source: G::Vertex) -> DijkstraResult +pub fn dijkstra(graph: &G, source: G::Vertex, weight: W) -> DijkstraResult where G: GraphTopology, + W: Fn(G::Edge) -> u32, { let mut predecessors = graph.vertex_map(None); - let distances = dijkstra_impl(graph, source, |neighbor, predecessor| { + let distances = dijkstra_impl(graph, source, weight, |neighbor, predecessor| { predecessors[neighbor] = Some(predecessor); }); DijkstraResult { @@ -41,21 +42,44 @@ where } } -pub fn dijkstra_distances(graph: &G, source: G::Vertex) -> VertexMap> +pub fn dijkstra_unweighted(graph: &G, source: G::Vertex) -> DijkstraResult where G: GraphTopology, { - dijkstra_impl(graph, source, |_, _| {}) + dijkstra(graph, source, |_| 1) } -// TODO: Add a way to provide custom edge weights for Dijkstra's algorithm. -fn dijkstra_impl( +pub fn dijkstra_distances( graph: &G, source: G::Vertex, + weight: W, +) -> VertexMap> +where + G: GraphTopology, + W: Fn(G::Edge) -> u32, +{ + dijkstra_impl(graph, source, weight, |_, _| {}) +} + +pub fn dijkstra_distances_unweighted( + graph: &G, + source: G::Vertex, +) -> VertexMap> +where + G: GraphTopology, +{ + dijkstra_distances(graph, source, |_| 1) +} + +fn dijkstra_impl( + graph: &G, + source: G::Vertex, + weight: W, mut on_relax: F, ) -> VertexMap> where G: GraphTopology, + W: Fn(G::Edge) -> u32, F: FnMut(G::Vertex, G::Vertex), { let mut distances = graph.vertex_map(None); @@ -69,6 +93,7 @@ where while let Some(v) = heap.pop() { for neighbor in graph.neighbors(v.vertex) { + // TODO: Use custom edge weights in Dijkstra's algorithm. let edge_weight = 1; let new_distance = distances[v.vertex].unwrap() + edge_weight; if match distances[neighbor] { diff --git a/tests/dijkstra.rs b/tests/dijkstra.rs index d816106..6b45023 100644 --- a/tests/dijkstra.rs +++ b/tests/dijkstra.rs @@ -6,7 +6,7 @@ use grapherity::traits::GraphTopology; fn dijkstra_single_vertex() { let mut graph = AppendGraph::new(); let v1 = graph.add_vertex(); - let result = algorithms::dijkstra(&graph, v1); + let result = algorithms::dijkstra_unweighted(&graph, v1); assert_eq!( result.distances[v1], Some(0), @@ -23,7 +23,7 @@ fn dijkstra_disconnected() { let mut graph = AppendGraph::new(); let v1 = graph.add_vertex(); let v2 = graph.add_vertex(); - let result = algorithms::dijkstra(&graph, v1); + let result = algorithms::dijkstra_unweighted(&graph, v1); assert_eq!( result.distances[v1], Some(0), @@ -46,7 +46,7 @@ fn dijkstra_disconnected() { #[test] fn dijkstra() { let (graph, vertices) = make_test_graph(); - let result = algorithms::dijkstra(&graph, vertices[0]); + let result = algorithms::dijkstra_unweighted(&graph, vertices[0]); let expected_distances_from_v0 = [ Some(0), Some(1), @@ -90,7 +90,7 @@ fn dijkstra() { fn dijkstra_distances_single_vertex() { let mut graph = AppendGraph::new(); let v1 = graph.add_vertex(); - let distances = algorithms::dijkstra_distances(&graph, v1); + let distances = algorithms::dijkstra_distances_unweighted(&graph, v1); assert_eq!( distances[v1], Some(0), @@ -103,7 +103,7 @@ fn dijkstra_distances_disconnected() { let mut graph = AppendGraph::new(); let v1 = graph.add_vertex(); let v2 = graph.add_vertex(); - let distances = algorithms::dijkstra_distances(&graph, v1); + let distances = algorithms::dijkstra_distances_unweighted(&graph, v1); assert_eq!( distances[v1], Some(0), @@ -118,7 +118,7 @@ fn dijkstra_distances_disconnected() { #[test] fn dijkstra_distances() { let (graph, vertices) = make_test_graph(); - let distances = algorithms::dijkstra_distances(&graph, vertices[0]); + let distances = algorithms::dijkstra_distances_unweighted(&graph, vertices[0]); let expected_distances_from_v0 = [ Some(0), Some(1),