开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情
由于Prim算法和Kruskal 算法设计思路的不同,导致了其对不同问题实例的效率对比关系的不同。所以这篇文章主要针对其中的两个问题进讨论
背景知识
Prim算法
-
输入:一个加权连通图,其中顶点集合为V,边集合为E
-
初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;
-
重复下列操作,直到Vnew = V:
a. 在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b. 将v加入集合Vnew中,将<u, v>边加入集合Enew中;
-
输出:使用集合Vnew和Enew来描述所得到的最小生成树。
Kruskal算法
克鲁斯卡尔(Kruskal)算法从另一途径求网的最小生成树。其基本思想是:假设连通网G=(V,E),令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),概述图中每个顶点自成一个连通分量。在E中选择代价最小的边,若该边依附的顶点分别在T中不同的连通分量上,则将此边加入到T中;否则,舍去此边而选择下一条代价最小的边。依此类推,直至T中所有顶点构成一个连通分量为止
如何将两种算法集成,以适应问题的不同实例输入
Prim算法基于顶点进行搜索的,适合于顶点少边多的稠密图。而Kruskal算法,基于边集合中进行搜索,更适用于边较少的稀疏图。
所以说在不同实例输入时,先进行一些判定,根据图中顶点和边的情况,边少时选用Kruskal算法,顶点少时选用Prim算法。
将两种算法集成,我们可以维护一个点集和边集,把每一个MST看做是一个点,把生成过程中的MST里面点集的相互连接的边从边集合中去除。
通过定点和边数的阈值来进行判断,假设开始是顶点少边多的稠密图,因此对应地使用Prim算法去生成MST,当顶点和边数到达某一阈值的时候,稠密图变成边较少的稀疏图时,可以切换为Kruskal算法进行运算。类似地,稀疏图到稠密图也可以这样做。
这一集成的意义
没有一个算法的万能的,任何算法都需要面对具体的情况进行对应的设计,才能发挥出最优的效率。所以设计算法需要具体问题具体分析,要充分了解问题的本质,不能胡乱套用算法框架,要知道再好的算法也有运行效率最差的情况出现。
感觉意义不是很大,因为不同的算法需要结合具体情况进行分析,才能算出最优解,不能随便选用算法进行计算,每一种算法都有其合适的适用范围。