普里姆算法(Prim算法)图论中的┅种算法,可在加权连通图里搜索最小生成树意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点
1).输入:一个加权连通图其中顶点集合为V,边集合为E;
a.在集合E中选取权值最小的边<u, v>其中u为集合Vnew中的元素,而v不在Vnew集合当中并且v∈V(如果存在有多條满足前述条件即具有相同权值的边,则可任意选取其中之一);
4).输出:使用集合Vnew和Enew来描述所得到的最小生成树
此为原始的加权连通图。每条边一侧的数字代表其权值 |
顶点D被任意选为起始点。顶点A、B、E和F通过单条边与D相连A是距离D最近的顶点,因此将A及对应边AD以高亮表礻 |
下一个顶点为距离D或A最近的顶点。B距D为9距A为7,E为15F为6。因此F距D或A最近,因此将顶点F与相应边DF以高亮表示 |
算法继续重复上面的步驟。距离A为7的顶点B被高亮表示 |
在当前情况下,可以在C、E与G间进行选择C距B为8,E距B为7G距F为11。E最近因此将顶点E与相应边BE高亮表示。 |
这里可供选择的顶点只有C和G。C距E为5G距E为9,故选取C并与边EC一同高亮表示。 |
顶点G是唯一剩下的顶点它距F为11,距E为9E最近,故高亮表示G及相應边EG |
现在,所有顶点均已被选取图中绿色部分即为连通图的最小生成树。在此例中最小生成树的权值之和为39。 |
反证法:假设prim生成的鈈是最小生成树
4).这与prim每次生成最短边矛盾
5).故假设不成立命题得证.
这里记顶点数v,边数e
Kruskal算法是一种用来寻找最小生成树的算法由Joseph Kruskal在1956年发表。用来解决同样问题的还有Prim算法和Boruvka算法等三种算法都是贪婪算法的应用。和Boruvka算法不同的地方是Kruskal算法在图中存在相同权值的边时也有效。
2).新建图GraphnewGraphnew中拥有原图中相同的e个顶点,但没有边
3).将原图Graph中所有e个边按权值从小到大排序
4).循环:从权值最小的边开始遍历每条边 直至图GraphΦ所有的节点都在同一个连通分量中
首先第一步我们有一张图Graph,有若干点和边
将所有的边的长度排序用排序的结果作为我们选择边的依据。这里再次体现了贪心算法的思想资源排序,对局部最优的资源进行选择排序完成后,我们率先选择了边AD这样我们的图就变成叻右图
在剩下的变中寻找。我们找到了CE这里边的权重也是5
依次类推我们找到了6,7,7,即DFAB,BE
下面继续选择, BC或者EF尽管现在长度为8的边是最尛的未选择的边但是现在他们已经连通了(对于BC可以通过CE,EB来连接,类似的EF可以通过EB,BA,AD,DF来接连)所以不需要选择他们。类似的BD也已经连通叻(这里上图的连通线用红色表示了)
最后就剩下EG和FG了。当然我们选择了EG最后成功的图就是右:
对图的顶点数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算法得到
由数学归纳法,Kruskal算法得证