生活中最小生成樹的應用十分廣泛,比如:要連通n個城市需要n-1條邊線路,那麼怎麼樣建設才能使工程造價最小呢?可以把線路的造價看成權值求這幾個城市的連通圖的最小生成樹。求最小造價的過程也就轉化成求最小生成樹的過程,則最小生成樹表示使其造價最小的生成樹。
那麼怎麼樣用普利姆算法(prim算法)求最小生成樹(MST)?
本文以圖例方式詳述prim算法求最小生成樹過程,希望對大家有幫助!
相關概念
帶權圖:邊賦以權值的圖稱爲網或帶權圖,帶權圖的生成樹也是帶權的,生成樹T各邊的權值總和稱爲該樹的權。
最小生成樹(MST):權值最小的生成樹。
生成樹和最小生成樹的應用:要連通n個城市需要n-1條邊線路。可以把邊上的權值解釋爲線路的造價,則最小生成樹表示使其造價最小的生成樹。
最小生成樹的性質
MST性質:假設G=(V,E)是一個連通網,U是頂點V的一個非空子集。若(u,v)是一條具有最小權值的邊,其中u∈U,v∈V-U,則必存在一棵包含邊(u,v)的最小生成樹。
構造網的最小生成樹必須解決下面兩個問題:
(1)儘可能選取權值小的邊,但不能構成迴路;
(2)選取n-1條恰當的邊以連通n個頂點;
普利姆算法(prim算法)基本思想
prim算法基本思想:
假設G=(V,E)是連通的,TE是G上最小生成樹中邊的集合。算法從U={u0}(u0∈V)、TE={}開始。重複執行下列操作:
在所有u∈U,v∈V-U的邊(u,v)∈E中找一條權值最小的邊(u0,v0)併入集合TE中,同時v0併入U,直到V=U爲止。
此時,TE中必有n-1條邊,T=(V,TE)爲G的最小生成樹。
Prim算法的核心:始終保持TE中的邊集構成一棵生成樹。
看了上面一大段文字是否感覺有點暈?爲了便於大家更好的理解,接下來進行算法過程的分步圖解!
普利姆求最小生成樹算法過程圖解
第一步:隨意選取起點
圖中有9個頂點v1-v9,集合表示爲:V={v1,…,V9},每條邊的邊權值都在圖上;在進行prim算法時,我們先隨意選擇一個頂點作爲起始點(起始點的選取不會影響最小生成樹結果),在此我們一般選擇v1作爲起始點,現在我們設U集合爲當前所找到最小生成樹裏面的頂點,TE集合爲所找到的邊。
狀態如下:U={v1}; TE={};
第二步:在前一步的基礎上尋找最小權值
查找一個頂點在U={v1}集合中,另一個頂點在V-U集合中的最小權值,如下圖,在紅線相交的線上找最小值。
通過圖中我們可以看到邊v1-v8的權值最小爲2,那麼將v8加入到U集合,(v1,v8)加入到TE。
狀態如下:U={v1,v8}; TE={(v1,v8)};
第三步:繼續尋找最小權值
查找一個頂點在U={v1,v8}集合中,另一個頂點在V-U集合中的最小權值,如下圖,在紅線相交的線上找最小值。
通過圖中我們可以看到邊v8-v9的權值最小爲4,那麼將v9加入到U集合,(v8,v9)加入到TE。
狀態如下:U={v1,v8,v9}; TE={(v1,v8),(v8,v9)};
第四步:在前一步的基礎上,繼續尋找最小權值
查找一個頂點在U={v1,v8,v9}集合中,另一個頂點在V-U集合中的最小權值,如下圖,在紅線相交的線上找最小值。
通過圖中我們可以看到邊v9-v2的權值最小爲1,那麼將v2加入到U集合,(v9,v2)加入到TE。
狀態如下:U={v1,v8,v9,v2};
TE={(v1,v8),(v8,v9),(v9,v2)};
第五步:繼續在前一步的基礎上,尋找最小權值
查找一個頂點在U={v1,v8,v9,v2}集合中,另一個頂點在V-U集合中的最小權值,如下圖,在紅線相交的線上找最小值。
通過圖中我們可以看到邊v2-v3的權值最小爲3,那麼將v3加入到U集合,(v2,v3)加入到TE。
狀態如下:U={v1,v8,v9,v2,v3};
TE={(v1,v8),(v8,v9),(v9,v2),(v2,v3)};
第五~九步:繼續在前一步的基礎上,尋找最小權值
如此循環一下直到找到所有頂點爲止。到這大家應該對普利姆算法求解最小生成樹的過程有所知曉,但需注意以下三點:
(1)每次都選取權值最小的邊,但不能構成迴路,構成環路的邊則捨棄。如圖中的(v1,v9),(v1,v2)等構成迴路捨棄
(2)遇到權值相等,又均不構成迴路的邊,隨意選擇哪一條,均不影響生成樹結果。如圖中的(v3,v4),(v6,v5)權值均爲9,選擇哪一條在先均不影響最小生成樹的生成結果。
(3)選取n-1條恰當的邊以連通n個頂點。
完整的算法步驟如圖所示:
總結
(1)最小生成樹(MST)是指權值最小的生成樹。
(2)prim算法是求最小生成樹的算法之一,其他算法還有kruskal算法
(3)其時間複雜度爲O(n^2),與邊得數目無關,prim算法適合稠密圖。