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 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
|
where
|
||||||
G: GraphTopology,
|
G: GraphTopology,
|
||||||
|
W: Fn(G::Edge) -> u32,
|
||||||
{
|
{
|
||||||
let mut predecessors = graph.vertex_map(None);
|
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);
|
predecessors[neighbor] = Some(predecessor);
|
||||||
});
|
});
|
||||||
DijkstraResult {
|
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
|
where
|
||||||
G: GraphTopology,
|
G: GraphTopology,
|
||||||
{
|
{
|
||||||
dijkstra_impl(graph, source, |_, _| {})
|
dijkstra(graph, source, |_| 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add a way to provide custom edge weights for Dijkstra's algorithm.
|
pub fn dijkstra_distances<G, W>(
|
||||||
fn dijkstra_impl<G, F>(
|
|
||||||
graph: &G,
|
graph: &G,
|
||||||
source: G::Vertex,
|
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,
|
mut on_relax: F,
|
||||||
) -> VertexMap<G::Vertex, Option<u32>>
|
) -> VertexMap<G::Vertex, Option<u32>>
|
||||||
where
|
where
|
||||||
G: GraphTopology,
|
G: GraphTopology,
|
||||||
|
W: Fn(G::Edge) -> u32,
|
||||||
F: FnMut(G::Vertex, G::Vertex),
|
F: FnMut(G::Vertex, G::Vertex),
|
||||||
{
|
{
|
||||||
let mut distances = graph.vertex_map(None);
|
let mut distances = graph.vertex_map(None);
|
||||||
@@ -69,6 +93,7 @@ where
|
|||||||
|
|
||||||
while let Some(v) = heap.pop() {
|
while let Some(v) = heap.pop() {
|
||||||
for neighbor in graph.neighbors(v.vertex) {
|
for neighbor in graph.neighbors(v.vertex) {
|
||||||
|
// TODO: Use custom edge weights in Dijkstra's algorithm.
|
||||||
let edge_weight = 1;
|
let edge_weight = 1;
|
||||||
let new_distance = distances[v.vertex].unwrap() + edge_weight;
|
let new_distance = distances[v.vertex].unwrap() + edge_weight;
|
||||||
if match distances[neighbor] {
|
if match distances[neighbor] {
|
||||||
|
|||||||
+6
-6
@@ -6,7 +6,7 @@ use grapherity::traits::GraphTopology;
|
|||||||
fn dijkstra_single_vertex() {
|
fn dijkstra_single_vertex() {
|
||||||
let mut graph = AppendGraph::new();
|
let mut graph = AppendGraph::new();
|
||||||
let v1 = graph.add_vertex();
|
let v1 = graph.add_vertex();
|
||||||
let result = algorithms::dijkstra(&graph, v1);
|
let result = algorithms::dijkstra_unweighted(&graph, v1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.distances[v1],
|
result.distances[v1],
|
||||||
Some(0),
|
Some(0),
|
||||||
@@ -23,7 +23,7 @@ fn dijkstra_disconnected() {
|
|||||||
let mut graph = AppendGraph::new();
|
let mut graph = AppendGraph::new();
|
||||||
let v1 = graph.add_vertex();
|
let v1 = graph.add_vertex();
|
||||||
let v2 = graph.add_vertex();
|
let v2 = graph.add_vertex();
|
||||||
let result = algorithms::dijkstra(&graph, v1);
|
let result = algorithms::dijkstra_unweighted(&graph, v1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.distances[v1],
|
result.distances[v1],
|
||||||
Some(0),
|
Some(0),
|
||||||
@@ -46,7 +46,7 @@ fn dijkstra_disconnected() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn dijkstra() {
|
fn dijkstra() {
|
||||||
let (graph, vertices) = make_test_graph();
|
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 = [
|
let expected_distances_from_v0 = [
|
||||||
Some(0),
|
Some(0),
|
||||||
Some(1),
|
Some(1),
|
||||||
@@ -90,7 +90,7 @@ fn dijkstra() {
|
|||||||
fn dijkstra_distances_single_vertex() {
|
fn dijkstra_distances_single_vertex() {
|
||||||
let mut graph = AppendGraph::new();
|
let mut graph = AppendGraph::new();
|
||||||
let v1 = graph.add_vertex();
|
let v1 = graph.add_vertex();
|
||||||
let distances = algorithms::dijkstra_distances(&graph, v1);
|
let distances = algorithms::dijkstra_distances_unweighted(&graph, v1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
distances[v1],
|
distances[v1],
|
||||||
Some(0),
|
Some(0),
|
||||||
@@ -103,7 +103,7 @@ fn dijkstra_distances_disconnected() {
|
|||||||
let mut graph = AppendGraph::new();
|
let mut graph = AppendGraph::new();
|
||||||
let v1 = graph.add_vertex();
|
let v1 = graph.add_vertex();
|
||||||
let v2 = 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!(
|
assert_eq!(
|
||||||
distances[v1],
|
distances[v1],
|
||||||
Some(0),
|
Some(0),
|
||||||
@@ -118,7 +118,7 @@ fn dijkstra_distances_disconnected() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn dijkstra_distances() {
|
fn dijkstra_distances() {
|
||||||
let (graph, vertices) = make_test_graph();
|
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 = [
|
let expected_distances_from_v0 = [
|
||||||
Some(0),
|
Some(0),
|
||||||
Some(1),
|
Some(1),
|
||||||
|
|||||||
Reference in New Issue
Block a user