Release 0.2.4 #7

Merged
warrence merged 19 commits from release-0.2.4 into main 2026-07-31 09:38:27 +02:00
Showing only changes of commit 08b2c4db65 - Show all commits
+128 -7
View File
@@ -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,