交互式图论学习
交互式图论学习
Guest User
Using app without sign in
并行最小生成树计算器
通过基于组件的并行方法找到MST
选择算法并生成步骤以开始可视化
Boruvka 算法发表于 1926 年,是最古老的 MST 算法,它让每个分量同时选出自己最便宜的出边,从而找到最小生成树。所有被选的边一次性加入,在并行的轮次中合并分量。
每一轮扫描所有边,为每个分量记录离开它的最小权重边。这些边被加入森林,使分量数至少减半,因此只需 O(log V) 轮。每轮花费 O(E),总计 O(E log V)。由于每轮都是简单的并行扫描,Boruvka 是并行与分布式 MST 计算的天然基础。
Boruvka 算法最初为规划摩拉维亚的电网而设计,如今支撑 GPU 和集群上的并行 MST 实现,以及将 Boruvka 轮次与 Prim 或 Kruskal 阶段混合的算法。在面试中,它主要作为并行算法设计的讨论点出现。
每个连通分量各自选出自己最便宜的出边,然后所有这些选择被一次性应用。它以「轮」而非「单步」推进,这正是它可以并行化的根本原因。
Boruvka(图):
对每个结点执行 建立集合(v)
mst = []
当剩余分量多于一个时:
最便宜 = {} // 按分量记录
对每条边 (u, v, w):
a = 查找(u); b = 查找(v)
若 a == b: 跳过 // 分量内部边
若 w < 最便宜[a]: 最便宜[a] = (u,v,w)
若 w < 最便宜[b]: 最便宜[b] = (u,v,w)
对 最便宜 中的每条边 e:
若 查找(e.u) != 查找(e.v): // 可能已被合并
合并(e.u, e.v); mst.追加(e)第二个循环里的那道守卫是必需的,而不是出于谨慎才加的。两个分量常常会从各自一端选中同一条边,若不加判断就应用两次,便会重复加入。正确性还要求边权互不相同,或者有一条一致的打破并列的规则,例如比较边的编号:若没有这样的规则,多个分量可能各自选中一条权重相同但不同的边,合起来恰好构成一个环。
在与 Prim 和 Kruskal 完全相同的图上构造最小生成树,以便三者可以直接对照。
示例图: 无向边 A-B (2)、A-C (3)、B-C (1)、C-D (4) 和 B-D (7)。
最小生成树由 A-B、B-C 和 C-D 构成,总权重为 2 + 1 + 4 = 7,与 Prim 和 Kruskal 得到的是同一棵树。Boruvka 只用一轮就完成,而不是三个先后相继的步骤,这正是它的要点:每一轮至少把分量数减半,因为每个分量都会与至少一个其他分量合并,所以永远不需要超过 O(log V) 轮。在这个四结点的例子里,一轮便已足够。
时间: O(E log V) · 空间: O(V + E)
每一轮以 O(E) 扫过全部边,为每个分量找出最便宜的出边。在一轮之内每个分量都会与至少一个其他分量合并,因此分量数至少减半,这把轮数限制在以 2 为底 V 的对数以内。两者相乘得到 O(E log V),与 Prim 和 Kruskal 相同。它真正与众不同之处在于:在同一轮内每个分量彼此独立地工作,因此这次扫描可以直接并行化,这也是 Boruvka 成为 GPU 与分布式最小生成树实现基础的原因,而 Prim 与 Kruskal 天生是串行的。混合算法会先跑几轮 Boruvka 把图缩小,再切换到 Prim 收尾。
三种经典的最小生成树算法复杂度都是 O(E log V),区别在于结构。
| 替代算法 | 以下情况更合适 | 代价 |
|---|---|---|
| Prim 算法 | 稠密图上的串行代码。一棵树、一个优先队列,实现简单。 | O(E log V) 或 O(V^2) |
| Kruskal 算法 | 稀疏图或边已预先排序,以及可以接受森林结果的非连通图。 | O(E log E) |
| Boruvka 算法 | 并行或分布式执行,因为每一轮都是按分量独立进行的扫描。 | O(E log V) |
| Boruvka 与 Prim 的混合 | 超大规模图。先用几轮 Boruvka 收缩图,再由 Prim 在更小的图上完成。 | 实践中约 O(E log log V) |
相关算法: 普里姆最小生成树算法, 克鲁斯卡尔最小生成树算法