最小生成樹演算法

2022-02-01 10:41:20 字數 4382 閱讀 3418

問題描述:

生成樹:在乙個任意連通圖g中,如果取它的全部頂點和一部分邊構成乙個子圖g',即:v(g')=v(g)和(g')⊆e(g)。若子圖g'同時滿足邊集e(g')中的所有邊既能夠使全部頂點連通而又不形成任何迴路,則稱子圖g'是原圖g的一棵生成樹。

乙個任意連通圖g=(v,e)的生成樹g'=(v,e』),那麼 |e'| = |v| - 1。

要證明這一特點有許多角度,例如:

加權連通圖g的最小生成樹:在所有的g的生成樹t中,使得邊的權值之和最小的生成樹。 

輸入:無向連通圖g=(v, e),權函式w

輸出:g的最小生成樹

kruskal()演算法與prim()演算法的差別以及聯絡:

kruskal()演算法與prim()演算法都是每次選取最小的邊,不過kruskal()演算法是滿足條件的邊,而prim()演算法選取點,依次選取離當前點集合最近的點。

演算法1:kruskal()演算法

演算法描述:

1. 確定貪心思想

其實求g的最小生成樹就是求最小生成樹的邊集,依照下述思想構建最小生成樹的邊集s:

2. 分析貪心選擇性。

引理1:設uv是g中權值最小的邊,則必有一棵g的最小生成樹包含邊uv。

證明:如果不存在這樣的乙個最小生成樹,那麼可以設:設t是g的的某棵最小生成樹,且uv不在t中,那麼,在t中新增uv邊,產生環,刪除環中不同於uv的任意邊xy,得到t '。w(t ')=w(t ) - w(xy) + w(uv) ≤ w(t),而t是g的的某棵最小生成樹,矛盾,假設不成立。

3.分析優化子結構

定義1:收縮略圖g的邊uv,即用新頂點c代替頂點u,v,同時,將g中原來與u或v關聯的邊與c關聯,刪除c到其自身的邊。記作g·uv。而將上述操作的逆操作稱為擴張,記作g.uv。

定義2:任意樹的權值記為w(t),w(t) = ∑(u,v)∈vw(u,v),w(i,j)是邊ij的權值。

引理2:給定加權無向連通圖g=(v,e),權值函式為 w:e→r, uv是g中權值最小的邊。設t是g的最小生成樹,那麼t·uv就是圖g·uv的最小生成樹。

證明:如果g.uv不是圖g.uv的最小生成樹。那麼一定存在樹m是g.uv的最小生成樹,那麼w(m.uv) =  w(m) + w(u,v),而w(t) = w(t·uv) + w(u,v)。而w(t·uv) > w(m),故而w(t) > w(m.uv)。這與t是g的最小生成樹矛盾,故而假設不成立。

4.分析演算法正確性

其貪心選擇性就是按照該演算法思想構造解的數學歸納證明,使用引理1,引理2可以得到證明。此問題的解的構造不若任務安排問題可以進行很好的形式化,就不展開說明。

5.設計演算法

根據貪心思想設計演算法。

mst-kruskal(g,w)

a = null;

for 任意的v屬於v[g] do

make-set(v); /*為每個點構建並查集*/

按照w值的遞增順序排序e[g];

for 任意(u, v)屬於e[g] (按w值的遞增順序) do

if find-set(u) != find-set(v)

/*u,v不在乙個並查集中,說明此時構建的樹中,二者之間不存在路*/

then a=au;

union(u, v);

return a

6.演算法複雜性分析:時間複雜性分析: 

n=|v|, m=|e|,那麼

第3~4行執行 o(n) 個make-set操作。第6~10行執行o(m)個find-set和union 操作。共需要時間o((n+m)α(n))。

而由於m ≥ n-1 (連通圖),故而 α(n)=logn=logm。這裡需要使用到並查集的平攤分析。

總的時間複雜度為 o(mlogm)。

演算法2:prim()演算法

演算法描述:

1. 確定貪心思想

其實求g的最小生成樹就是求最小生成樹的邊集,依照下述思想構建最小生成樹的邊集s:

2. 分析貪心選擇性。

引理1:設uv是g中與頂點u關聯的權值最小的邊,u為任意頂點,則必有一棵g的最小生成樹包含邊uv

證明:如果不存在這樣的乙個最小生成樹,那麼可以設:t是g的的某棵最小生成樹,且uv不在t中,那麼,在t中新增uv邊,產生環,刪除環中不同於uv的任意邊uv ',由於uv不在t中,故而一定存在uv 。得到t '。w(t ')=w(t ) - w(xy) + w(uv) ≤ w(t),而t是g的的某棵最小生成樹,矛盾,假設不成立。

3.分析優化子結構

引理2:給定加權無向連通圖g=(v,e),權值函式為 w:e→r, uv是g中與u關聯的權值最小的邊,u為任意頂點。設t是g的最小生成樹,那麼t·uv就是圖g.uv的最小生成樹。

證明:如果g·uv不是圖g.uv的最小生成樹。那麼一定存在樹m是g.uv的最小生成樹,那麼w(m.uv) =  w(m) + w(u,v),而w(t) = w(t·uv) + w(u,v)。而w(t·uv) > w(m),故而w(t) > w(m.uv)。這與t是g的最小生成樹矛盾,故而假設不成立。

4.分析演算法正確性

其貪心選擇性就是按照該演算法思想構造解的數學歸納證明,使用引理1,引理2可以得到證明。此問題的解的構造不若任務安排問題可以進行很好的形式化,就不展開說明。

5.設計演算法

根據貪心思想設計演算法。

mst-prim(g,w,r)

input 連通圖g,權值函式w,樹根r

output g的一棵以r為根的生成樹

c = ,t = null;

建堆q維護c與v-c之間的邊

while c != v do

uv=extract_min(q) //u屬於c,v不屬於v-c

c = c u;

t = t u;

for 任意的x屬於adj[v] do /*adj[v]是與v之間存在邊的頂點集*/

if x屬於c then 將vx從q中刪除

else 將vx插入q

return t

使用二叉最小堆來進行具體的撰寫,我看不懂。

mst-prim(g,w,r)

input 連通圖g,權值函式w,樹根r

output g的一棵以r為根的生成樹

for 任意的v屬於v[g] do

key[v] = 無窮;

π[v] = null;

key[r] = 0;

q = v[g];

while q != null do

u = extract_min(q);

for 任意的v屬於adj[u] do /*adj[v]是與v之間存在邊的頂點集*/

if v屬於q 且 w(u,v)

6.演算法複雜性分析:

對於該問題的拓展思考

最小生成樹演算法

由帶權的連通圖生成的數的各邊加起來稱為生成樹的權,把權值最小的生成樹稱為最小生成樹 minimum spanning tree 簡稱為mst 構造最小生成樹的方法就是利用mst性質,一條一條地選擇可以加入的邊。下面介紹兩種用於構造最小生成樹的演算法,其中第一種演算法稱為prim演算法,第二種演算法稱...

最小生成樹演算法

乙個最簡單的最小生成樹 圖結構練習 最小生成樹 time limit 1000ms memory limit 65536k 有n個城市,其中有些城市之間可以修建公路,修建不同的公路費用是不同的。現在我們想知道,最少花多少錢修公路可以將所有的城市連在一起,使在任意一城市出發,可以到達其他任意的城市。輸...

演算法 最小生成樹

前言 最小生成樹是在乙個給定的無向圖中求一棵樹,這棵樹包含無向圖中的所有頂點,且樹中的邊都來自無向圖中的邊,並且要滿足整棵樹的邊權之和最小。1 最小生成樹是樹,其邊數等於頂點數減1,且不會有環 2 對於給定的圖最小生成樹可以不唯一,但是邊權之和一定是唯一的。3 其根節點可以是這棵樹上的任何乙個節點,...