Release 0.2.4 #7
+128
-7
@@ -1,3 +1,33 @@
|
||||
//! Algorithms for graph topologies.
|
||||
//!
|
||||
//! # Dijkstra's algorithm
|
||||
//!
|
||||
//! [Dijkstra's algorithm] finds the shortest distances from a source vertex to all other vertices
|
||||
//! in the graph. Note that for unweighted graphs it has worse time and space complexity than
|
||||
//! [Breadth-first search](#breadth-first-search).
|
||||
//!
|
||||
//! Variants: [`dijkstra`], [`dijkstra_distances`], [`dijkstra_unweighted`],
|
||||
//! [`dijkstra_distances_unweighted`].
|
||||
//!
|
||||
//! # Breadth-first search
|
||||
//!
|
||||
//! [Breadth-first search] traverses a graph topology, exploring all neighboring vertices first
|
||||
//! before descending further into their neighborhoods.
|
||||
//!
|
||||
//! Variants: [`bfs`], [`bfs_distances`], [`bfs_find`], [`bfs_find_where`]
|
||||
//!
|
||||
//! # Depth-first search
|
||||
//!
|
||||
//! [Depth-first search] traverses a graph topology, exploring each branch path as far as possible
|
||||
//! first before backtracking and exploring other branches.
|
||||
//!
|
||||
//! Variants: [`dfs`], [`dfs_visited`], [`dfs_find`], [`dfs_find_where`], [`dfs_find_path`],
|
||||
//! [`dfs_find_path_where`]
|
||||
//!
|
||||
//! [Breadth-first search]: https://en.wikipedia.org/wiki/Breadth-first_search
|
||||
//! [Depth-first search]: https://en.wikipedia.org/wiki/Depth-first_search
|
||||
//! [Dijkstra's algorithm]: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::{BinaryHeap, VecDeque};
|
||||
|
||||
@@ -22,12 +52,39 @@ impl<V: Eq> Ord for DistanceOrderedVertex<V> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Return data type for [`dijkstra`] and [`dijkstra unweighted`].
|
||||
pub struct DijkstraResult<V: Copy> {
|
||||
/// Vertex map of minimum distances from a given `source` vertex.
|
||||
pub distances: VertexMap<V, Option<u32>>,
|
||||
|
||||
/// Vertex map of predecessors on some shortest path from a given `source` vertex.
|
||||
pub predecessors: VertexMap<V, Option<V>>,
|
||||
}
|
||||
|
||||
// TODO: Generalize the return type of the weight function.
|
||||
/// Dijkstra's algorithm with custom edge weights, returns minimum distances and predecessors.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `source` is not a valid vertex of `graph`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use grapherity::prelude::*;
|
||||
/// # use grapherity::algorithms::dijkstra;
|
||||
/// # use grapherity::models::Graph;
|
||||
/// let mut graph = Graph::new();
|
||||
/// let source = graph.add_vertex();
|
||||
/// let target = graph.add_vertex();
|
||||
/// let e = graph.add_edge(source, target);
|
||||
/// let mut weights = graph.edge_map(1);
|
||||
/// weights[e] = 5;
|
||||
///
|
||||
/// let result = dijkstra(&graph, source, |e| weights[e]);
|
||||
/// assert_eq!(result.distances[target], Some(5));
|
||||
/// assert_eq!(result.predecessors[target], Some(source));
|
||||
/// ```
|
||||
pub fn dijkstra<G, W>(graph: &G, source: G::Vertex, weight: W) -> DijkstraResult<G::Vertex>
|
||||
where
|
||||
G: GraphTopology,
|
||||
@@ -43,13 +100,28 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dijkstra_unweighted<G>(graph: &G, source: G::Vertex) -> DijkstraResult<G::Vertex>
|
||||
where
|
||||
G: GraphTopology,
|
||||
{
|
||||
dijkstra(graph, source, |_| 1)
|
||||
}
|
||||
|
||||
/// Dijkstra's algorithm with custom edge weights, returns minimum distances.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `source` is not a valid vertex of `graph`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use grapherity::prelude::*;
|
||||
/// # use grapherity::algorithms::{dijkstra, dijkstra_distances};
|
||||
/// # use grapherity::models::Graph;
|
||||
/// let mut graph = Graph::new();
|
||||
/// let source = graph.add_vertex();
|
||||
/// let target = graph.add_vertex();
|
||||
/// let e = graph.add_edge(source, target);
|
||||
/// let mut weights = graph.edge_map(1);
|
||||
/// weights[e] = 5;
|
||||
///
|
||||
/// let distances = dijkstra_distances(&graph, source, |e| weights[e]);
|
||||
/// assert_eq!(distances[target], Some(5));
|
||||
/// ```
|
||||
pub fn dijkstra_distances<G, W>(
|
||||
graph: &G,
|
||||
source: G::Vertex,
|
||||
@@ -62,6 +134,55 @@ where
|
||||
dijkstra_impl(graph, source, weight, |_, _| {})
|
||||
}
|
||||
|
||||
/// Dijkstra's algorithm with constant weights of *1* for all edges, returns minimum distances and
|
||||
/// predecessors.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `source` is not a valid vertex of `graph`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use grapherity::prelude::*;
|
||||
/// # use grapherity::algorithms::{dijkstra, dijkstra_unweighted};
|
||||
/// # use grapherity::models::Graph;
|
||||
/// let mut graph = Graph::new();
|
||||
/// let source = graph.add_vertex();
|
||||
/// let target = graph.add_vertex();
|
||||
/// graph.add_edge(source, target);
|
||||
///
|
||||
/// let result = dijkstra_unweighted(&graph, source);
|
||||
/// assert_eq!(result.distances[target], Some(1));
|
||||
/// assert_eq!(result.predecessors[target], Some(source));
|
||||
/// ```
|
||||
pub fn dijkstra_unweighted<G>(graph: &G, source: G::Vertex) -> DijkstraResult<G::Vertex>
|
||||
where
|
||||
G: GraphTopology,
|
||||
{
|
||||
dijkstra(graph, source, |_| 1)
|
||||
}
|
||||
|
||||
/// Dijkstra's algorithm with constant weights of *1* for all edges, returns minimum distances.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `source` is not a valid vertex of `graph`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use grapherity::prelude::*;
|
||||
/// # use grapherity::algorithms::{dijkstra, dijkstra_distances_unweighted};
|
||||
/// # use grapherity::models::Graph;
|
||||
/// let mut graph = Graph::new();
|
||||
/// let source = graph.add_vertex();
|
||||
/// let target = graph.add_vertex();
|
||||
/// graph.add_edge(source, target);
|
||||
///
|
||||
/// let distances = dijkstra_distances_unweighted(&graph, source);
|
||||
/// assert_eq!(distances[target], Some(1));
|
||||
/// ```
|
||||
pub fn dijkstra_distances_unweighted<G>(
|
||||
graph: &G,
|
||||
source: G::Vertex,
|
||||
|
||||
Reference in New Issue
Block a user