簡體   English   中英

Kruskal算法解釋

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM