YUAN 2019-06-26
这篇文章由 最小生成树-Prim算法和Kruskal算法 整理而来, 感谢这篇文章的作者
普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现;并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现;1959年,艾兹格·迪科斯彻再次发现了该算法。因此,在某些场合,普里姆算法又被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法。
重复下列操作,直到 Vnew = V:
4 .输出:使用集合 Vnew 和 Enew 来描述所得到的最小生成树。
下面对算法的图例描述
反证法:假设prim生成的不是最小生成树
// to be done ...
Prime算法主要用于边比较多, 点比较少的时候
这里记顶点数v,边数e
邻接矩阵:O(v2)
邻接表:O(e * log2v)
Kruskal算法是一种用来寻找最小生成树的算法,由Joseph Kruskal在1956年发表。用来解决同样问题的还有 Prime 算法和 Boruvka 算法等。三种算法都是贪婪算法的应用。和 Boruvka 算法不同的地方是,Kruskal 算法在图中存在相同权值的边时也有效。
如果这条边连接的两个节点于图 Graphnew 中不在同一个连通分量中
添加这条边到图 Graphnew 中
图例描述:
对图的顶点数 n 做归纳,证明 Kruskal 算法对任意 n 阶图适用。
归纳基础:
n = 1,显然能够找到最小生成树。
归纳过程:
假设 Kruskal 算法对 n ≤ k 阶图适用,那么,在 k + 1 阶图 G 中,我们把最短边的两个端点 a 和 b 做一个合并操作,即把 u 与 v 合为一个点 v',把原来接在 u 和 v 的边都接到 v' 上去,这样就能够得到一个 k阶图 G'(u ,v 的合并是 k + 1 少一条边),G' 最小生成树 T' 可以用Kruskal 算法得到。
我们证明 T' + {<u,v>} 是 G 的最小生成树。
用反证法,如果 T' + {<u,v>} 不是最小生成树,最小生成树是 T,即W(T) < W(T' + {<u,v>})。显然 T 应该包含 <u,v>,否则,可以用<u,v> 加入到 T 中,形成一个环,删除环上原有的任意一条边,形成一棵更小权值的生成树。而T - {<u,v>},是 G' 的生成树。所以 W(T-{<u,v>}) <= W(T'),也就是 W(T) <= W(T') + W(<u,v>) = W(T'+{<u,v>}),产生了矛盾。于是假设不成立,T' + {<u,v>}是 G 的最小生成树,Kruskal 算法对 k+1 阶图也适用。
由数学归纳法,Kruskal 算法得证。
// to be done ...
Kruskal算法主要用于边比较少, 点比较多的时候
e * log2e (e为图中的边数)
一颗有n个顶点的生成树有且仅有n-1条边,如果生成树中再添加一条边,则必定成环。此算法可以称为“加边法”,初始最小生成树边数为0,每迭代一次就选择一条满足条件的最小代价边,加入到最小生成树的边集合里。