图的并行最小生成森林算法
我先从“生成森林”这个概念开始。
在无向图中,生成森林是指一个包含原图所有顶点的无环子图(即若干棵树组成的森林),且每条边都属于原图。如果原图是连通的,生成森林就退化为生成树;如果原图不连通,生成森林的每个连通分量是原图某个连通分量的生成树。
步骤1:最小生成森林问题
给定一个带权无向图,目标是在每个连通分量中找一棵生成树,使得这些树的边权之和最小。这称为最小生成森林(Minimum Spanning Forest, MSF)。
如果图是连通的,MSF 就是最小生成树(MST)。经典算法有 Kruskal 和 Prim 算法,它们本质是贪心法,基于“切割性质”和“环性质”。
步骤2:并行化的动机
当图非常大时,串行 MST 算法(复杂度 O(m log n) 或 O(m + n log n))仍然可能太慢。我们需要利用多处理器或分布式系统加速。并行算法的目标是在更少的时间(或轮数)内得到 MSF,同时工作量(所有处理器总操作数)尽可能接近最优。
步骤3:并行算法的主要思路
并行 MSF 算法通常分为两类:
- 边过滤法:通过安全删除一些不可能在 MSF 中的边来减少问题规模,重复直到边数接近 n 数量级,再用串行算法。
- 分治法:将图划分成子图,在各子图上并行计算部分生成森林,再合并。
一个经典并行框架基于 Borůvka 算法(也称为 Sollin 算法):
- 每轮每个连通分量选择其最小权出边(minimum outgoing edge, MOE)。
- 将这些边加入生成森林,从而将分量合并。
- 每轮分量数至少减半,因此最多 O(log n) 轮结束。
Borůvka 算法易于并行化,因为每个顶点/分量可以独立寻找 MOE。
步骤4:具体并行步骤(基于 Borůvka 的并行 MSF)
假设有 p 个处理器,图用邻接表分布存储。
- 初始化:每个顶点是一个连通分量。
- 重复以下步骤直到所有顶点在同一个分量中(对连通图)或各分量内部已形成生成树:
a. 对每个分量,并行地找出连接该分量到其它分量的边中权值最小的边(MOE)。这一步需要对每个顶点的邻边做局部最小查找,再在分量内部归约。
b. 将这些 MOE 边加入生成森林边集。
c. 根据加入的边合并连通分量(用并查集并行化,需要小心并发合并的冲突,常用“指针跳转”等技术)。
d. 重标记顶点所属的新分量,并可选地压缩图(将每个分量缩成一个超顶点,边权保留连接不同分量的边中的最小边权)。 - 输出加入的所有边构成的 MSF。
步骤5:复杂度分析
在 PRAM(并行随机存取机器)模型下,如果允许并发读和并发写(CRCW),Borůvka 并行算法可以在 O(log n) 轮内完成,总工作量 O(m log n),但通过更精细的实现(如配合边过滤)可以减少总工作量到 O(m)。在实际分布式或并行计算中,还要考虑通信开销和负载均衡。
步骤6:其他并行 MST 算法
除了 Borůvka 并行化,还有:
- 并行 Kruskal 算法:需要对边排序(可并行排序),之后并行连通性检测较困难。
- 并行 Prim 算法:需要优先队列的并行化,较复杂。
- 基于样本的并行算法(如 Klein 和 Tarjan 的线性工作量随机算法):先采样一部分边构造一个较稀疏的图,在该图上找 MSF,再处理剩下边。
步骤7:实际应用与挑战
在大规模图计算系统(如 MapReduce、Pregel、Spark)中,并行 MSF 常用于网络设计、聚类等任务。挑战包括:
- 如何避免合并分量时的数据竞争。
- 如何分布图数据以减少通信。
- 如何在不规则图上保持负载均衡。
这样,我们就从生成森林的基本定义,循序渐进地走到了并行最小生成森林算法的原理、步骤和实际挑战。