Prim算法和Kruskal 算法的异同点

255 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情

由于Prim算法和Kruskal 算法设计思路的不同,导致了其对不同问题实例的效率对比关系的不同。所以这篇文章主要针对其中的两个问题进讨论

背景知识

Prim算法

  1. 输入:一个加权连通图,其中顶点集合为V,边集合为E

  2. 初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;

  3. 重复下列操作,直到Vnew = V:

    a. 在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);

    b. 将v加入集合Vnew中,将<u, v>边加入集合Enew中;

  4. 输出:使用集合Vnew和Enew来描述所得到的最小生成树。

111.jpg

Kruskal算法

克鲁斯卡尔(Kruskal)算法从另一途径求网的最小生成树。其基本思想是:假设连通网G=(V,E),令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),概述图中每个顶点自成一个连通分量。在E中选择代价最小的边,若该边依附的顶点分别在T中不同的连通分量上,则将此边加入到T中;否则,舍去此边而选择下一条代价最小的边。依此类推,直至T中所有顶点构成一个连通分量为止

111.jpg

如何将两种算法集成,以适应问题的不同实例输入

Prim算法基于顶点进行搜索的,适合于顶点少边多的稠密图。而Kruskal算法,基于边集合中进行搜索,更适用于边较少的稀疏图。

所以说在不同实例输入时,先进行一些判定,根据图中顶点和边的情况,边少时选用Kruskal算法,顶点少时选用Prim算法。

将两种算法集成,我们可以维护一个点集和边集,把每一个MST看做是一个点,把生成过程中的MST里面点集的相互连接的边从边集合中去除。

通过定点和边数的阈值来进行判断,假设开始是顶点少边多的稠密图,因此对应地使用Prim算法去生成MST,当顶点和边数到达某一阈值的时候,稠密图变成边较少的稀疏图时,可以切换为Kruskal算法进行运算。类似地,稀疏图到稠密图也可以这样做。

这一集成的意义

没有一个算法的万能的,任何算法都需要面对具体的情况进行对应的设计,才能发挥出最优的效率。所以设计算法需要具体问题具体分析,要充分了解问题的本质,不能胡乱套用算法框架,要知道再好的算法也有运行效率最差的情况出现。

感觉意义不是很大,因为不同的算法需要结合具体情况进行分析,才能算出最优解,不能随便选用算法进行计算,每一种算法都有其合适的适用范围。