The minimum spanning tree of a graph(图的最小生成树)

来源:互联网 发布:刷微信阅读量软件 编辑:程序博客网 时间:2024/06/18 09:22

Q: minimum spanning tree 的定义

A: 给定一幅图G = (V,E), 找到E的一个能够连接起G中所有的节点(vertices)的边子集T, 并且边子集的权重之和最小, 这就是我们所说的最小生成树



由于T是无环的, 并且联通所有的节点, 所以T然是一棵树。 我们称T为图G的 minimum spanning tree。 

上图(graph)的minimum spanning tree(即T) 为:



所以现在问题是 , 给定一个具有weighted edges 的graph G, 找到G的最小生成树T。


解决这个问题的有两个算法。 一个是prim's algorithm, 以前的博客已经介绍到。 还有一个算法是Kruskal Algorithm 来找到图G的minimum spanning tree.下面主要介绍Kruskal‘s algorithm. 

 Kruskal's algorithm 使用到了disjoint-set 的概念。算法伪代码如下:


下面对于上述图, 使用Kruskal's algorithm 的运算过程。

  由于Disjoint set 具有2 个重要的operations, 即Find 和 Union, Kruskal‘s algorithm 利用了Disjoint-set 的知识。   Find 的作用是take an item, 返回的是代表这个   item 所在集合的代表。 

Union take 2 disjoint-set,  and merge them into one disjoint set。

根据上面的伪代码, 下面给出解释。

首先,  集合A存储是是MST(最小生成树)的边的集合。 所以initially, A 被初始化为空集∅。 eventually, Kruskal’s Algorithm 返回的也是A(此时A中含有MST的所有的边)。

然后, 对于图中的每一个vertex, 我们都创建 具有一个元素的Disjoint-set(single vertex Disjoint set)


然后对于图中的所有边E, 按照边权重, 对其按照从小到达的顺序排序。 所以, 对于上图, edge with the smallest weight will be in the front, 此例子中, 权重最小的边为1的那个. 具有最大权重的边在最后(为6)等等。


接下来, 从排好序的边集合中选择边。 当然, 首先选择排在最前面的边, 即1。 等等。

如果这个边的两个顶点v1 和v2 不再同一个Disjoint-set 中, 我们就push that edge into A, and then merge the two disjoint-set(ie, v1, v2) into one。


循环完成之后, 最终返回A。


现在讨论分析下图运用Kruskal‘s algorithm 的算法 如下。

step1: 选中具有最小权重的边(当然1(即(c, f)边)在最前面), 即为连接c和f 的边。 由于c和f 属于不同的Disjoint-set, 所以我们merge them, and then push the edge into A:



step2: 下一个具有权重为2的边, 例如先选中a f。 由于二者属于不同的Disjoint-set, 所以我们merge them, and then push the edge into A:




等等, 依次类推, 有如下各个图:

step3:



step4:


step5:

接下来, 假如说首先选中边e, f(权重为4), 但是由于e, f 属于同一个Disjoint-set, 所以we will not push this edge in to A。


step6:




最终, 我们得到个这个图的MST(当然具有minimum weight)。


代码见下个博客。 









0 0