//! 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;