Update Dijkstra's algorithm to use VertexMap
This commit is contained in:
+18
-17
@@ -1,6 +1,7 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::BinaryHeap;
|
use std::collections::BinaryHeap;
|
||||||
|
|
||||||
|
use crate::maps::VertexMap;
|
||||||
use crate::traits::GraphTopology;
|
use crate::traits::GraphTopology;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
@@ -21,19 +22,18 @@ impl<V: Eq> Ord for DistanceOrderedVertex<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DijkstraResult<V> {
|
pub struct DijkstraResult<V: Copy> {
|
||||||
pub distances: Vec<Option<u32>>,
|
pub distances: VertexMap<V, Option<u32>>,
|
||||||
pub predecessors: Vec<Option<V>>,
|
pub predecessors: VertexMap<V, Option<V>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dijkstra<G>(graph: &G, source: G::Vertex) -> DijkstraResult<G::Vertex>
|
pub fn dijkstra<G>(graph: &G, source: G::Vertex) -> DijkstraResult<G::Vertex>
|
||||||
where
|
where
|
||||||
G: GraphTopology,
|
G: GraphTopology,
|
||||||
G::Vertex: Into<usize>,
|
|
||||||
{
|
{
|
||||||
let mut predecessors = vec![None; graph.vertex_count()];
|
let mut predecessors = graph.vertex_map(None);
|
||||||
let distances = dijkstra_impl(graph, source, |neighbor, predecessor| {
|
let distances = dijkstra_impl(graph, source, |neighbor, predecessor| {
|
||||||
predecessors[neighbor.into()] = Some(predecessor);
|
predecessors[neighbor] = Some(predecessor);
|
||||||
});
|
});
|
||||||
DijkstraResult {
|
DijkstraResult {
|
||||||
distances,
|
distances,
|
||||||
@@ -41,25 +41,27 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dijkstra_distances<G>(graph: &G, source: G::Vertex) -> Vec<Option<u32>>
|
pub fn dijkstra_distances<G>(graph: &G, source: G::Vertex) -> VertexMap<G::Vertex, Option<u32>>
|
||||||
where
|
where
|
||||||
G: GraphTopology,
|
G: GraphTopology,
|
||||||
G::Vertex: Into<usize>,
|
|
||||||
{
|
{
|
||||||
dijkstra_impl(graph, source, |_, _| {})
|
dijkstra_impl(graph, source, |_, _| {})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Replace Vec storage with VertexMap, this should make the bound on G::Vertex here obsolete.
|
// TODO: Add a way to provide custom edge weights for Dijkstra's algorithm.
|
||||||
fn dijkstra_impl<G, F>(graph: &G, source: G::Vertex, mut on_relax: F) -> Vec<Option<u32>>
|
fn dijkstra_impl<G, F>(
|
||||||
|
graph: &G,
|
||||||
|
source: G::Vertex,
|
||||||
|
mut on_relax: F,
|
||||||
|
) -> VertexMap<G::Vertex, Option<u32>>
|
||||||
where
|
where
|
||||||
G: GraphTopology,
|
G: GraphTopology,
|
||||||
G::Vertex: Into<usize>,
|
|
||||||
F: FnMut(G::Vertex, G::Vertex),
|
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();
|
let mut heap = BinaryHeap::new();
|
||||||
|
|
||||||
distances[source.into()] = Some(0);
|
distances[source] = Some(0);
|
||||||
heap.push(DistanceOrderedVertex {
|
heap.push(DistanceOrderedVertex {
|
||||||
vertex: source,
|
vertex: source,
|
||||||
distance: 0,
|
distance: 0,
|
||||||
@@ -67,15 +69,14 @@ 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: Add a way to provide custom edge weights for Dijkstra's algorithm.
|
|
||||||
let edge_weight = 1;
|
let edge_weight = 1;
|
||||||
let new_distance = distances[v.vertex.into()].unwrap() + edge_weight;
|
let new_distance = distances[v.vertex].unwrap() + edge_weight;
|
||||||
if match distances[neighbor.into()] {
|
if match distances[neighbor] {
|
||||||
None => true,
|
None => true,
|
||||||
Some(old_distance) if old_distance > new_distance => true,
|
Some(old_distance) if old_distance > new_distance => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
} {
|
} {
|
||||||
distances[neighbor.into()] = Some(new_distance);
|
distances[neighbor] = Some(new_distance);
|
||||||
on_relax(neighbor, v.vertex);
|
on_relax(neighbor, v.vertex);
|
||||||
heap.push(DistanceOrderedVertex {
|
heap.push(DistanceOrderedVertex {
|
||||||
vertex: neighbor,
|
vertex: neighbor,
|
||||||
|
|||||||
Reference in New Issue
Block a user