[英]Kruskal's algorithm explanation
我正在閱讀Wikipeida,並發現以下Kruskal的偽代碼:
KRUSKAL(G):
foreach v ∈ G.V:
MAKE_SET(v)
G.E = sort(G.E)
i = 0
while (i != |V|-1):
pick the next (u, v) edge from sorted list of edges G.E
if (FIND_SET(u) != FIND_SET(v)):
UNION(u, v)
i = i + 1
我不能確定FIND_SET()
作用,而Wikipedia具有以下描述:
如果該邊緣連接了兩棵不同的樹,則將其添加到森林中,將兩棵樹合並為一棵樹。
因此,我猜它會檢查是否連接了兩個不同的樹,但這到底意味着什么?
最初,每個頂點本身都是一個集合:每個頂點v
有一個單例集合{v}
。 在偽代碼中,這些集合是make_set(v)
的結果。
對於給定的頂點v
,函數find_set(v)
為您提供包含v
的集合。
該算法以迭代方式合並集合,因此,如果{u}
, {v}
最初是單例集合並且存在邊(u, v)
,則該算法將兩個集合用其並集{u, v}
替換。 現在, find_set(u)
和find_set(v)
都將返回該集合。
添加|V| - 1
后,算法終止 |V| - 1
非平凡的邊,恰好是樹中的邊數。
FIND_SET(x)查找與邊x相關的集合,以便進行比較:
FIND_SET(u) != FIND_SET(v)
確保u和v沒有連接到同一事物。 一種有用的思考方式是,它找到u和v的“值”,這些值本身就是集合。
關於合並森林的部分與FIND_SET無關,而是下一行:
UNION(u,v)
合並兩個集合。
find_set()
是一種稱為Union-Find的數據結構的常見操作。 這種數據結構的想法是具有不相交的集合(在您的示例中為頂點)。
在這種算法中,我認為每個集合代表連接的頂點。
因此,當您調用傳遞頂點的find_set()
,您將收到表示該組已連接頂點的元素。
find_set(u)!=find_set(v)
表示生成樹的基本屬性是不生成循環,如果相等,則表示圖中存在一個循環。
我們基本上是通過Kruskal算法建立一個(具有最小邊緣權重的)森林,並在每一步都檢查它是否在循環。
希望能幫助到你 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.