Rust图算法库graaf的使用,graaf提供高效图数据结构和算法实现,支持有向无向图的常见操作
以下是基于您提供内容整理的Rust graaf库使用示例,包含基础图操作和Dijkstra算法实现:
基础有向图操作示例
use graaf::{
repr::AdjacencyList,
op::{
AddArc,
HasArc,
Order,
Size,
Vertices,
},
};
fn main() {
// 创建空有向图(邻接表表示)
let mut digraph = AdjacencyList::new();
// 添加边(弧)
digraph.add_arc(0, 1); // 0 → 1
digraph.add_arc(0, 2); // 0 → 2
digraph.add_arc(1, 2); // 1 → 2
digraph.add_arc(2, 0); // 2 → 0 (形成环)
digraph.add_arc(2, 3); // 2 → 3
// 检查边存在性
println!("边 0->1 存在? {}", digraph.has_arc(0, 1)); // true
println!("边 1->0 存在? {}", digraph.has_arc(1, 0)); // false
// 图的基本属性
println!("顶点数量: {}", digraph.order()); // 4
println!("边数量: {}", digraph.size()); // 5
// 遍历所有顶点
println!("顶点列表:");
for v in digraph.vertices() {
println!("- {}", v);
}
}
带权图与Dijkstra算法示例
use graaf::{
repr::AdjacencyListWeighted,
algo::dijkstra::Dijkstra,
};
fn main() {
// 创建带权有向图
let mut digraph = AdjacencyListWeighted::new();
// 添加带权边
digraph.add_arc_weighted(0, 1, 4); // 0 → 1 (权重4)
digraph.add_arc_weighted(0, 2, 2); // 0 → 2 (权重2)
digraph.add_arc_weighted(1, 2, 5); // 1 → 2 (权重5)
digraph.add_arc_weighted(1, 3, 10); // 1 → 3 (权重10)
digraph.add_arc_weighted(2, 3, 3); // 2 → 3 (权重3)
// 计算从顶点0出发的最短路径
let distances = Dijkstra::distances(&digraph, 0);
println!("从顶点0出发的最短距离:");
for (vertex, distance) in distances.iter() {
println!("- 到达顶点 {}: {}", vertex, distance);
}
}
示例说明
-
基础图操作展示:
- 创建邻接表表示的有向图
- 添加边/弧
- 检查边的存在性
- 获取图的阶(顶点数)和大小(边数)
- 遍历所有顶点
-
Dijkstra算法展示:
- 创建带权有向图
- 添加带权边
- 计算单源最短路径
- 输出源点到各顶点的最短距离
graaf库支持的其他算法:
- 广度优先搜索(BFS)
- 深度优先搜索(DFS)
- Floyd-Warshall全源最短路径算法
- Tarjan强连通分量算法
- 特殊图生成(完全图/星图/轮图等)
这两个示例覆盖了graaf库的基础用法,您可以通过组合这些操作实现更复杂的图算法应用。
1 回复
Rust图算法库graaf的使用指南
graaf是一个高效的Rust图算法库,提供了多种图数据结构和常用算法的实现,支持有向图和无向图的操作。
安装
在Cargo.toml中添加依赖:
[dependencies]
graaf = "0.1"
基本使用
创建图
use graaf::Graph;
// 创建有向图
let mut directed_graph = Graph::new_directed();
// 创建无向图
let mut undirected_graph = Graph::new_undirected();
添加顶点和边
// 添加顶点
directed_graph.add_vertex("A");
directed_graph.add_vertex("B");
directed_graph.add_vertex("C");
// 添加边
directed_graph.add_edge("A", "B", 1); // A -> B 权重1
directed_graph.add_edge("B", "C", 2); // B -> C 权重2
directed_graph.add_edge("C", "A", 3); // C -> A 权重3
常用操作
遍历图
// 深度优先搜索(DFS)
let dfs_order = directed_graph.dfs("A");
println!("DFS order: {:?}", dfs_order);
// 广度优先搜索(BFS)
let bfs_order = directed_graph.bfs("A");
println!("BFS order: {:?}", bfs_order);
最短路径
use graaf::algo::dijkstra;
// 使用Dijkstra算法计算最短路径
if let Some((path, cost)) = dijkstra(&directed_graph, "A", "C") {
println!("Shortest path from A to C: {:?}, cost: {}", path, cost);
} else {
println!("No path found from A to C");
}
拓扑排序
if let Ok(order) = directed_graph.topological_sort() {
println!("Topological order: {:?}", order);
} else {
println!("Graph contains cycles");
}
高级功能
最小生成树(Kruskal算法)
use graaf::algo::kruskal;
let mst = kruskal(&undirected_graph);
println!("Minimum spanning tree edges: {:?}", mst);
强连通分量
use graaf::algo::kosaraju;
let sccs = kosaraju(&directed_graph);
println!("Strongly connected components: {:?}", sccs);
性能提示
- 对于大型图,考虑使用
Graph::with_capacity
预先分配空间 - 频繁查询邻居时,邻接表表现更好
- 需要快速判断边是否存在时,邻接矩阵更合适
graaf库提供了灵活而高效的图操作接口,适合各种图论算法的实现和应用场景。
完整示例代码
use graaf::{Graph, algo::{dijkstra, kruskal, kosaraju}};
fn main() {
// 1. 创建有向图
let mut directed_graph = Graph::new_directed();
// 添加顶点
directed_graph.add_vertex("A");
directed_graph.add_vertex("B");
directed_graph.add_vertex("C");
directed_graph.add_vertex("D");
// 添加边
directed_graph.add_edge("A", "B", 1); // A -> B 权重1
directed_graph.add_edge("B", "C", 2); // B -> C 权重2
directed_graph.add_edge("C", "A", 3); // C -> A 权重3
directed_graph.add_edge("A", "D", 4); // A -> D 权重4
// 2. 图遍历
println!("DFS from A: {:?}", directed_graph.dfs("A"));
println!("BFS from A: {:?}", directed_graph.bfs("A"));
// 3. 最短路径
match dijkstra(&directed_graph, "A", "C") {
Some((path, cost)) => println!("最短路径 A->C: {:?}, 权重: {}", path, cost),
None => println!("未找到路径 A->C"),
}
// 4. 拓扑排序
match directed_graph.topological_sort() {
Ok(order) => println!("拓扑排序: {:?}", order),
Err(_) => println!("图中存在环"),
}
// 5. 创建无向图
let mut undirected_graph = Graph::new_undirected();
undirected_graph.add_vertex("A");
undirected_graph.add_vertex("B");
undirected_graph.add_vertex("C");
undirected_graph.add_edge("A", "B", 1);
undirected_graph.add_edge("B", "C", 2);
undirected_graph.add_edge("C", "A", 3);
// 6. 最小生成树
println!("最小生成树边: {:?}", kruskal(&undirected_graph));
// 7. 强连通分量
println!("强连通分量: {:?}", kosaraju(&directed_graph));
}