Add weight parameter for Dijkstra's algorithm, add unweighted variants (unused)
This commit is contained in:
+31
-6
@@ -27,12 +27,13 @@ pub struct DijkstraResult<V: Copy> {
|
||||
pub predecessors: VertexMap<V, Option<V>>,
|
||||
}
|
||||
|
||||
pub fn dijkstra<G>(graph: &G, source: G::Vertex) -> DijkstraResult<G::Vertex>
|
||||
pub fn dijkstra<G, W>(graph: &G, source: G::Vertex, weight: W) -> DijkstraResult<G::Vertex>
|
||||
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<G>(graph: &G, source: G::Vertex) -> VertexMap<G::Vertex, Option<u32>>
|
||||
pub fn dijkstra_unweighted<G>(graph: &G, source: G::Vertex) -> DijkstraResult<G::Vertex>
|
||||
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<G, F>(
|
||||
pub fn dijkstra_distances<G, W>(
|
||||
graph: &G,
|
||||
source: G::Vertex,
|
||||
weight: W,
|
||||
) -> VertexMap<G::Vertex, Option<u32>>
|
||||
where
|
||||
G: GraphTopology,
|
||||
W: Fn(G::Edge) -> u32,
|
||||
{
|
||||
dijkstra_impl(graph, source, weight, |_, _| {})
|
||||
}
|
||||
|
||||
pub fn dijkstra_distances_unweighted<G>(
|
||||
graph: &G,
|
||||
source: G::Vertex,
|
||||
) -> VertexMap<G::Vertex, Option<u32>>
|
||||
where
|
||||
G: GraphTopology,
|
||||
{
|
||||
dijkstra_distances(graph, source, |_| 1)
|
||||
}
|
||||
|
||||
fn dijkstra_impl<G, W, F>(
|
||||
graph: &G,
|
||||
source: G::Vertex,
|
||||
weight: W,
|
||||
mut on_relax: F,
|
||||
) -> VertexMap<G::Vertex, Option<u32>>
|
||||
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] {
|
||||
|
||||
+6
-6
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user