1. 程式人生 > >最小生成樹演算法:普里姆演算法和克魯斯卡爾演算法

最小生成樹演算法:普里姆演算法和克魯斯卡爾演算法

普里姆演算法—Prim演算法


演算法思路: 
從已選頂點所關聯的未選邊中找出權重最小的邊,並且生成樹不存在環。

其中,已選頂點是構成最小生成樹的結點,未選邊是不屬於生成樹中的邊。

(普里姆演算法與求最短路徑的迪傑斯塔拉演算法思想很類似)

 

下面我們對下面這幅圖求其最小生成樹:

è¿éåå¾çæè¿°

假設我們從頂點v1開始,所以我們可以發現(v1,v3)邊的權重最小,所以第一個輸出的邊就是:v1—v3=1: 

è¿éåå¾çæè¿°
然後,我們要從v1和v3作為起點的邊中尋找權重最小的邊,首先了(v1,v3)已經訪問過了,所以我們從其他邊中尋找,發現(v3,v6)這條邊最小,所以輸出邊就是:v3—-v6=4 

è¿éåå¾çæè¿°
然後,我們要從v1、v3、v6這三個點相關聯的邊中尋找一條權重最小的邊,我們可以發現邊(v6,v4)權重最小,所以輸出邊就是:v6—-v4=2. 

è¿éåå¾çæè¿°
然後,我們就從v1、v3、v6、v4這四個頂點相關聯的邊中尋找權重最小的邊,發現邊(v3,v2)的權重最小,所以輸出邊:v3—–v2=5 

è¿éåå¾çæè¿°
然後,我們就從v1、v3、v6、v4,v2這2五個頂點相關聯的邊中尋找權重最小的邊,發現邊(v2,v5)的權重最小,所以輸出邊:v2—–v5=3 

è¿éåå¾çæè¿°
最後,我們發現六個點都已經加入到集合U了,我們的最小生成樹建立完成。

克魯斯卡演算法


演算法思路: 


(1)將邊按權值從小到大的順序新增到新圖中,保證新增的過程中不會形成環 
(2)重複上一步直到連線所有頂點,此時就生成了最小生成樹。這是一種貪心策略。

將圖中所有邊按照權重的大小 從小到大一個一個按順序組合成最小生成樹,在組合過程新加入的邊會導致生成樹形成環,那這條邊就捨棄,直到所有頂點都新增到生成樹中為止。

這裡同樣我們給出一個和Prim演算法講解中同樣的例子,模擬克魯斯卡演算法生成最小生成樹的詳細的過程:

首先完整的圖如下圖: 

è¿éåå¾çæè¿°
然後,我們需要從這些邊中找出權重最小的那條邊,可以發現邊(v1,v3)這條邊的權重是最小的,所以我們輸出邊:v1—-v3=1 

è¿éåå¾çæè¿°
然後,我們需要在剩餘的邊中,再次尋找一條權重最小的邊,可以發現邊(v4,v6)這條邊的權重最小,所以輸出邊:v4—v6=2 

è¿éåå¾çæè¿°
然後,我們再次從剩餘邊中尋找權重最小的邊,發現邊(v2,v5)的權重最小,所以可以輸出邊:v2—-v5=3, 

è¿éåå¾çæè¿°
然後,我們使用同樣的方式找出了權重最小的邊:(v3,v6),所以我們輸出邊:v3—-v6=4 

è¿éåå¾çæè¿°
好了,現在我們還需要找出最後一條邊就可以構造出一顆最小生成樹,但是這個時候我們有三個選擇:(v1,V4),(v2,v3),(v3,v4),這三條邊的權重都是5,首先我們如果選(v1,v4)的話,得到的圖如下: 
 è¿éåå¾çæè¿°
我們發現,這肯定是不符合我們演算法要求的,因為它出現了一個環,所以我們再使用第二個(v2,v3)試試,得到圖形如下: 

è¿éåå¾çæè¿°
我們發現,這個圖中沒有環出現,而且把所有的頂點都加入到了這顆樹上了,所以(v2,v3)就是我們所需要的邊,所以最後一個輸出的邊就是:v2—-v3=5

OK,到這裡,我們已經把克魯斯卡演算法過了一遍
--------------------- 
轉載自:https://blog.csdn.net/qq_35644234/article/details/59106779?utm_source=copy