Prim算法
背景:
常常遇到的问题:给定n个点,把它们按照一种代价最低的方式连接起来,使得任意两点之间都存在一条路径。
介绍:
用途的顶点来表示上述问题的点,可能的连接用途的边来表示,而连接的成本则用边的权重表示。那么上述问题就可以表示成最小生成树问题,下面给出它的正式定义。
最小生成树定义:
连通图的一颗生成树(spanning tree)是包含图的所有顶点的连通无环子图(也就是一棵树)。加权连通图的一颗最小生成树(minimum spanning tree)是图的一颗权重最小的生成树,其中,树的权重(weight)定义为所有边的权重总和。最小生成树问题(minimum spanning tree problem)就是求一个给定的加权连通图的最小生成树问题。
如果视图用一种穷举查找算法来构造一棵最小生成树,会遇到两个严重的障碍。
首先,随着图的规模的增长,生成树的数量呈指数增加(至少稠密图是如此)。
其次,生成一个给定图的所有生成图也并非易事。
Prim算法
Prim算法通过一系列不断扩张的子树来构造一棵最小生成树。
- 我们从图的顶点集合V中任意选择的一个单项点,作为序列中的初始子树。
- 每一次迭代时,以一种贪心的思想来扩张当前的生成树,即把不在树的最近顶点添加到树中(我们所说的最近顶点,是指一个不在树中的顶点,它以一条权重最小的边和树中的顶点相连,而树的形状是无所谓的)。
- 当图的所有顶点都包含在所构造的树中以后,该算法就停止了。
算法伪代码:
演示如何对一个特定的图应用Prim算法:
如果图是由邻接链表表示的,并且优先队列是由最小堆实现的, 该算法的运行时间属于 O ( ∣ E ∣ l o g ∣ V ∣ ) O(|E|log|V|) O(∣E∣log∣V∣)。
这是因为该算法执行丁 ∣ V ∣ − 1 |V|-1 ∣V∣−1次删除最小元素的操作,并且进行了 ∣ E ∣ |E| ∣E∣次验证,如有必要,还要对一个规模不大于 ∣ V ∣ |V| ∣V∣的最小堆改变其元素的优先级 就像我们前面提到的,每一种操作都是 O ( l o g ∣ V ) O(log|V) O(log∣V)的操作。
因此,Prim 算法的这种实现的运行时间属于 O ( ∣ E ∣ l o g ∣ V ∣ ) O(|E|log|V|) O(∣E∣log∣V∣)
小结:
Prim算法是一种加权连通图构造最小生成树的贪心算法。它的工作原理是向前面构造的一颗子树中添加离树中顶点最近的顶点。