Last Updated: 2024-04-27 03:25:43 Saturday
-- TOC --
《CLRS》讨论MST的前提是Connected Undirected but Weighted Graph。MST是一棵连接所有vertices的树,具备树中所有Edge权重和最小的特性。(注意与Shortest Path的区别,不一样的)
这是用来证明本文两个MST算法的Lemma中的关键概念。
Cut-Set是一个Edge的集成,它将所有的Vertex分成了至少两个parts。在Kruskal算法中,Cut-Set不是很明显,比如在算法最开始,parts的数量与vertex的数量一致。而在Prim算法中,始终能看到一个vertex不断增长的part。
Forest视角,每次选出一条Edge,满足Weight最小的同时不会形成Cycle。当所有Vertices都被连接时,就形成了MST。
sort all edges by cost in ascending order in E
T is initialized as an empty set
For each edge as e in E:
if T+{e} has no cycle:
T = T+{e}
T is MST
Kruskal算法的一个关键,在于如何高效的判断加入e之后T是否存在cycle。此时要用到disjoint set数据结构
(或称为union find),edge的两个vertice如果不属于同一个union,就可以放心加入,一定没有cycle。union在这里就成了connected components。如果假设find操作的复杂度为\(O(\log{V})\),union的复杂度为\(O(1)\),判断cycle的耗时与find相同,因此Kruskal的时间复杂度为\(O(E\log{V})\)。
Tree视角,算法从任意一个vertex开始,每次选出一条Edge,满足cost最小的同时,连接新的vertex,让这棵树生长,最后得到的就是MST。
Prim(G,v): # v is start vertex
S = {v}
T = an empty set
create a minheap as EH # Edge minHeap
add all edges of v to EH # edges in cut-set(S,V-S)
while |S| != |V|:
extract the minimum cost edge as e and (a,b) in EH
T = T + {e}
S = S + {b} # a is already in S
maintain EH # add all edges of b to EH,
# delete all edges (x,b) where x in S,
# that's the edges in cut-set(S,V-S)
T is MST
Prim算法与Dijstra算法很相似,但又有根本的区别。Prim算法中的Heap,只有edge的cost,Prim关注MST。Dijstra算法中的Heap,保存shortest path cost from source vertex,Dijstra关注SP。
所有edges都从heap中过了一遍,再加上extract操作,Prim算法的复杂度为\(O((E+V)\log{E})\)。
本文链接:https://cs.pynote.net/ag/graph/202404213/
-- EOF --
-- MORE --