156 lines
5.8 KiB
Rust
156 lines
5.8 KiB
Rust
//! Graph models and algorithms.
|
|
//!
|
|
//! This crate provides data structures to model graphs and to perform algorithms on these data
|
|
//! structures. The functionality presented is designed to be easy to use, flexible, and performant.
|
|
//!
|
|
//! Currently supported are:
|
|
//!
|
|
//! * Undirected graph types [`Graph`], [`AppendGraph`], and [`FrozenGraph`] built on a flat,
|
|
//! index-based adjacency list,
|
|
//! * [`ElementMap`] to freely associate custom data with vertices and edges,
|
|
//! * Connectivity and pathing algorithms: [Dijkstra's algorithm], [DFS], and [BFS] in different
|
|
//! variants,
|
|
//! * Exposed [`traits`] to implement custom graph data structures or algorithms.
|
|
//!
|
|
//! # Usage example
|
|
//!
|
|
//! This example demonstrates some of this library's features.
|
|
//!
|
|
//! ```
|
|
//! // Brings commonly used traits into scope.
|
|
//! use grapherity::prelude::*;
|
|
//! use grapherity::models::Graph;
|
|
//! use grapherity::algorithms;
|
|
//!
|
|
//! let mut graph = Graph::new();
|
|
//! // Adds three vertices and two edges.
|
|
//! let v1 = graph.add_vertex();
|
|
//! let v2 = graph.add_vertex();
|
|
//! let v3 = graph.add_vertex();
|
|
//! graph.add_edge(v1, v2);
|
|
//! let e = graph.add_edge(v2, v3);
|
|
//! // Creates a map for edge weights with a default weight, after creating the edges.
|
|
//! let mut weights = graph.edge_map(1);
|
|
//! // Sets a non-default weight for the second edge.
|
|
//! weights[e] = 5;
|
|
//!
|
|
//! // Checks the number of vertices.
|
|
//! assert_eq!(graph.vertex_count(), 3);
|
|
//! // Checks the number of edges.
|
|
//! assert_eq!(graph.edge_count(), 2);
|
|
//! // Checks that v1 and v2 are adjacent.
|
|
//! assert!(graph.are_adjacent(v1, v2));
|
|
//! // Checks that v1 and v3 are not adjacent.
|
|
//! assert!(!graph.are_adjacent(v1, v3));
|
|
//! // Checks the sum of all vertex degrees.
|
|
//! let sum: usize = graph.vertices().map(|v| graph.degree(v)).sum();
|
|
//! assert_eq!(sum, 1 + 2 + 1);
|
|
//!
|
|
//! // Calls Dijkstra's algorithm using the edge weights to find the shortest path from v1 to v3.
|
|
//! let result = algorithms::dijkstra(&graph, v1, |e| weights[e]);
|
|
//! assert_eq!(result.distances[v3], Some(1 + 5));
|
|
//! assert_eq!(result.predecessors[v3], Some(v2));
|
|
//!
|
|
//! // Deletes the middle vertex and its incident edges.
|
|
//! graph.delete_vertex(v2);
|
|
//!
|
|
//! // Calls Dijkstra's algorithm again on the now disconnected graph.
|
|
//! let result = algorithms::dijkstra(&graph, v1, |e| weights[e]);
|
|
//! assert_eq!(result.distances[v3], None);
|
|
//! assert_eq!(result.predecessors[v3], None);
|
|
//! ```
|
|
//!
|
|
//! # Graph types
|
|
//!
|
|
//! [`Graph`], [`AppendGraph`], and [`FrozenGraph`] all implement [`GraphTopology`] using a flat,
|
|
//! index-based adjacency list to store edges. Degree lookups run in `O(1)`.
|
|
//!
|
|
//! [`Graph`] and [`AppendGraph`] implement [`GraphTopologyAddition`], which provides functionality
|
|
//! for iterative graph construction. Vertex and edge insertions happen in `O(1)`.
|
|
//!
|
|
//! [`Graph`] additionally implements [`GraphTopologyDeletion`], thereby supporting deletion of
|
|
//! vertices and edges.
|
|
//!
|
|
//! [`AppendGraph`] does not support deletion, vertices and edges can only be added, allowing it to
|
|
//! be smaller and more performant compared to [`Graph`] by not requiring the per-element generation
|
|
//! tracking needed for stable handles after deletion.
|
|
//!
|
|
//! [`FrozenGraph`] uses a memory layout that is more cache-friendly for traversals than
|
|
//! [`AppendGraph`], but the trade-off is that its topology must be constructed during its
|
|
//! initialization. It cannot be modified afterward.
|
|
//!
|
|
//! # Vertices and edges
|
|
//!
|
|
//! Graphs in this library use stable indices [`GraphTopology::Vertex`] and [`GraphTopology::Edge`]
|
|
//! to denote vertices and edges. This means that vertices and edges returned by graph functions
|
|
//! never change, even if the underlying graph data structure is mutated. However, vertices and
|
|
//! edges can become invalid when the denoted element is deleted. Code using an invalid vertex or
|
|
//! edge in a graph method will panic.
|
|
//!
|
|
//! ```should_panic
|
|
//! # use grapherity::prelude::*;
|
|
//! # use grapherity::models::Graph;
|
|
//! let mut graph = Graph::new();
|
|
//! let v = graph.add_vertex();
|
|
//! graph.delete_vertex(v);
|
|
//! // This will panic because 'v' was deleted and is not valid anymore.
|
|
//! graph.degree(v);
|
|
//! ```
|
|
//!
|
|
//! [`ElementMap`] does not check validity of vertices or edges and might or might not panic in case
|
|
//! an invalid handle is provided.
|
|
//!
|
|
//! Vertices and edges are provided by the graph and not intended to be generated by users.
|
|
//!
|
|
//! # Loops and multi-edges
|
|
//!
|
|
//! Loops and multi edges are supported as well. In the following example, `v1` will have two loops
|
|
//! and two edges to `v2`.
|
|
//!
|
|
//! ```
|
|
//! # use grapherity::prelude::*;
|
|
//! # use grapherity::models::Graph;
|
|
//! let mut graph = Graph::new();
|
|
//! let v1 = graph.add_vertex();
|
|
//! let v2 = graph.add_vertex();
|
|
//! for _ in 0..2 {
|
|
//! graph.add_edge(v1, v1);
|
|
//! graph.add_edge(v1, v2);
|
|
//! }
|
|
//! assert_eq!(graph.edge_count(), 4);
|
|
//! assert_eq!(graph.degree(v1), 6);
|
|
//! ```
|
|
//!
|
|
//! [BFS]: algorithms::bfs
|
|
//! [Dijkstra's algorithm]: algorithms::dijkstra
|
|
//! [DFS]: algorithms::dfs
|
|
//! [`ElementMap`]: maps::ElementMap
|
|
//! [`AppendGraph`]: models::AppendGraph
|
|
//! [`FrozenGraph`]: models::FrozenGraph
|
|
//! [`Graph`]: models::Graph
|
|
//! [`traits`]: traits
|
|
//! [`GraphTopology`]: traits::GraphTopology
|
|
//! [`GraphTopology::Edge`]: traits::GraphTopology::Edge
|
|
//! [`GraphTopology::Vertex`]: traits::GraphTopology::Vertex
|
|
//! [`GraphTopologyAddition`]: traits::GraphTopologyAddition
|
|
//! [`GraphTopologyDeletion`]: traits::GraphTopologyDeletion
|
|
|
|
#![warn(missing_docs)]
|
|
|
|
pub mod algorithms;
|
|
pub mod generators;
|
|
pub mod maps;
|
|
pub mod models;
|
|
pub mod traits;
|
|
|
|
/// Convenience re-exports of graph topology traits for common use.
|
|
pub mod prelude {
|
|
pub use crate::traits::{
|
|
GraphIsomorphism, GraphTopology, GraphTopologyAddition, GraphTopologyConversion,
|
|
GraphTopologyDeletion, Incidence, IncidenceCursor,
|
|
};
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
pub mod testing;
|