| Crates.io | gryf |
| lib.rs | gryf |
| version | 0.1.0 |
| created_at | 2023-04-07 18:51:55.005021+00 |
| updated_at | 2025-08-22 15:46:43.810171+00 |
| description | Graph data structure library with focus on convenience, versatility, correctness and performance. |
| homepage | https://github.com/pnevyk/gryf |
| repository | https://github.com/pnevyk/gryf |
| max_upload_size | |
| id | 833115 |
| size | 868,605 |
Graph data structure library aspiring to be convenient, versatile, correct and performant.
Status: The library is not released on crates.io yet. It is incomplete, lacks documentation and contains bugs. Breaking changes are expected. Design contributions are very welcome!
gryf = { git = "https://github.com/pnevyk/gryf.git" }
use gryf::{algo::ShortestPaths, Graph};
fn main() {
// Default storage is adjacency list, but that can be simply changed by
// using `Graph::new_undirected_in`.
let mut graph = Graph::new_undirected();
let prague = graph.add_vertex("Prague");
let bratislava = graph.add_vertex("Bratislava");
let vienna = graph.add_vertex("Vienna");
let munich = graph.add_vertex("Munich");
let nuremberg = graph.add_vertex("Nuremberg");
let florence = graph.add_vertex("Florence");
let rome = graph.add_vertex("Rome");
graph.extend_with_edges([
(prague, bratislava, 328u32),
(prague, nuremberg, 297),
(prague, vienna, 293),
(bratislava, vienna, 79),
(nuremberg, munich, 170),
(vienna, munich, 402),
(vienna, florence, 863),
(munich, florence, 646),
(florence, rome, 278),
]);
// As the edge weights are unsigned and there is a specific goal, Dijktra's
// algorithm is applied. For signed edges, Bellman-Ford would be used.
let shortest_paths = ShortestPaths::on(&graph).goal(prague).run(rome).unwrap();
let distance = shortest_paths[prague];
let path = shortest_paths
.reconstruct(prague)
.map(|v| graph[v])
.collect::<Vec<_>>()
.join(" - ");
println!("{distance} km from Prague through {path}");
// 1391 km from Prague through Nuremberg - Munich - Florence - Rome
}
The main goals of gryf are to be
Failing in any of these should be considered an issue to be reported.
For more details, see the design doc.
It may not be obvious which algorithm should (or even can) be used to solve the
given problem at hand, especially for users without much experience or knowledge
in graph theory and algorithms. Instead, gryf organizes the algorithms into the
problem they solve (e.g., ShortestPaths) instead of requiring to call the
algorithms directly (dijkstra, bellman_ford).
Organizing algorithms into problems brings a number of benefits, among which the most important are:
Vec or HashMap
gives the opportunity to provide additional functionality (like path
reconstruction for shortest paths or "is perfect?" query on matching).let shortest_paths = ShortestPaths::on(&graph).run(rome).unwrap();
Specifying arguments for algorithms is done using the builder pattern. This
avoids the need to pass dummy values (like None) to parameters that are not
useful for the use case. On the other hand, it allows tweaking the algorithm
with many optional arguments. Moreover, new optional parameters can be added in
a backward-compatible way. A lot of care is taken to make the error feedback
from the compiler helpful and obvious.
let shortest_paths = ShortestPaths::on(&graph)
.edge_weight_fn(|e| e.distance)
.goal(prague)
.run(rome)
.unwrap();
High-level semantics provided by user-facing types are strictly separated from the underlying storage/representation. The graph data can be stored in a common representation (e.g., adjacency list or adjacency matrix), but it can also be stored in or represented by a custom, problem-tailored implementation, as long as it implements provided interfaces.
On top of storage, there is an encapsulation with clear semantics. The most general is a generic graph, but restricted forms include simple graphs (without parallel edges), paths, bipartite graphs and so on. Among the advantages of restrictive encapsulations are:
use gryf::storage::AdjMatrix;
let mut graph = Graph::new_undirected_in(AdjMatrix::default());
Check the rusty graphs repository for a detailed comparison of gryf and other graph libraries available for Rust with examples and commentary.
Dual-licensed under MIT and UNLICENSE. Feel free to use it, contribute or spread the word.