圖論之最小生成樹算法介紹

今天介紹兩個(gè)最常用的的最小生成樹算法,首先來說幾個(gè)概念:

所謂生成樹,通俗的說其實(shí)是原圖的中的所有頂點(diǎn)和一部分邊組成的一個(gè)子圖,這個(gè)子圖應(yīng)該滿足兩個(gè)性質(zhì),一是沒有環(huán)路,二是所有的頂點(diǎn)都有邊相連,不能出現(xiàn)孤立的點(diǎn)。由“連接所有點(diǎn)”和“沒有環(huán)路”這兩點(diǎn)可以得到一個(gè)簡單的結(jié)論:如果圖中有n個(gè)頂點(diǎn),則圖的生成樹應(yīng)該有n-1條邊。

所謂最小生成樹,是指一個(gè)無向圖的所有生成樹當(dāng)中邊的權(quán)重之和最小的生成樹。

目前有兩種解決最小生成樹的算法,他們的想法其實(shí)都特別簡單。第一種叫Kruskal算法,它的考慮是從邊出發(fā)的,每一步嘗試把所有剩余的邊中權(quán)重最小的邊加進(jìn)來,如果會(huì)導(dǎo)致產(chǎn)生回路的話就放棄,然后嘗試下一條邊。第二種叫Prim算法,它的考慮是基于頂點(diǎn)的,從起始頂點(diǎn)出發(fā),每一步選擇和已經(jīng)建好的生成樹相連的邊中最小權(quán)重的邊,這樣就能把下一個(gè)頂點(diǎn)拉到生成樹當(dāng)中來。

首先來介紹一個(gè)Kruskal算法:

假設(shè)G(V,E)是一個(gè)由n個(gè)頂點(diǎn),若干條邊組成的圖。我們先構(gòu)造一個(gè)只有n個(gè)頂點(diǎn),沒有邊的子圖T= { V, ? },算法開始的時(shí)候,這個(gè)子圖里面的點(diǎn)都是孤立的。

然后嘗試從E中選擇一條具有最小權(quán)值的邊放到子圖T當(dāng)中去,若該邊的兩個(gè)頂點(diǎn)目前還沒有別的路徑相連,則將此邊加入到T中;否則,即插入這條邊會(huì)產(chǎn)生回路,則將此邊舍去(此后永不選用這條邊)。然后重新選擇一條權(quán)值最小的邊。如此重復(fù)下去,直到所有頂點(diǎn)在同一個(gè)連通分量上為止。

這么說有些枯燥,我們來看個(gè)例子立即一下

上圖中左邊是一個(gè)無向連通圖,右邊是Kruskal算法的結(jié)果,括號(hào)里的數(shù)字是被選中的次序,可以看到這些邊是按照權(quán)重從小到大的順序被加進(jìn)去的。

接下來介紹一下Prim算法:

設(shè)連通無向圖為G(V,E),在Prim算法中,將頂點(diǎn)集合V分成兩個(gè)子集合T和T':

T:當(dāng)前生成樹頂點(diǎn)集合,

T':不屬于當(dāng)前生成樹的頂點(diǎn)集合。

很顯然有:T∪T'= V。

Prim算法的具體過程為:

首先無向圖G中選擇一個(gè)頂點(diǎn)作為起始點(diǎn),將它加入到集合T中;然后選擇與所有橫跨T與T’的邊中權(quán)重最小的邊e,將e在T’中的頂點(diǎn)從T’中刪除,然后加入到頂點(diǎn)集合T中。以后每一步都選擇橫跨T與T’中權(quán)重最小的邊,把它從T’中搬家搬到T中。如此繼續(xù)下去,直到網(wǎng)絡(luò)中的所有頂點(diǎn)都加入到生成樹頂點(diǎn)集合T中為止。還是上面的例子,看看Prim算法跑的結(jié)果。

從右圖中可以看出,Prim算法是按照一步步擴(kuò)大生成樹的方法插入邊的。

好了,最后把Kruskal和Prim算法的結(jié)果放在一起,大家感受一下區(qū)別

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容