使用貪心算法解決最小生成樹

生成樹的定義:對於一個圖G,獲取G的邊使得全部的頂點都鏈接到。最小生成樹(MST Minimun spanning tree):給定圖G(V,E),以及對應的邊的權重,獲取一顆總權重最小的生成樹。算法

樹的定義:鏈接的無環圖數據結構

直接策略

找到全部的生成樹,而後計算權重最小的cors

考慮上面的圖,一但紅色線選定,對於接下了的標號爲1,..,n的全部節點點,左右節點都只須要二選一便可獲得不一樣的生成樹,這樣的選擇有 2^n種,太多

貪心算法的性質

  1. 最優子結構:有多個子結構的最優解最終組成整個問題的最優解
  2. 貪心算法的選擇特定,會使得局部最優解最終也是全局最優解

尋找MST的最優子結構

假如邊e={u,v}是某個MST的一條邊,經過對合並這兩個頂點爲一個新的頂點(這種操做稱做contract e),將有多條邊同時鏈接多個頂點的合併成一個權重最小的邊保留,其它邊的鏈接形式保持不變。能夠證實假設T'是G/e(不包含e的G)的MST,那麼T'U{e}也是G的MST函數

證實

假設T*(e\in T^*)是G的MST,那麼 T*/e(即T') 也是 G/e的MST,即spa

w(T')\leq w(T^*/e)

而w(T'Ue)=w(T')+w(e),因此.net

w(T'Ue) \leq w(T^*/e)+w(e)=w(T^*)

於是成立3d

MST的貪心選擇

假設有任意的cut(S,V-S),選取e,使得e是全部crossing cut的最小權重的邊(e={u,v},u\in S v\in V-S),那麼e確定是屬於某個MST。code

紅色的線即 crossing cut的邊cdn

證實

假設T是G的一個MST,那麼它一定存在一條邊e'={u',v'}橫跨S和V/S,因爲w(e)<=w(e'),能夠構造T'=T/{e'}U{e}=w(T)-w(e')+w(e)<=w(T),也就是說T'也是MST,e屬於某個MST。blog

Prim's算法

維護一個優先級隊列Q,它的節點u.key=min{w(u,v)|u in s and v in (S-V)}

  • 隨便選取單個節點做爲S,其它的都是 S-V
  • 在Q中存儲V全部的節點,對於節點s,有s.key=0,其它的是 無窮大
  • 只要Q中還有元素,獲取最小的元素,遍歷它的鄰接表,若是節點v不在S裏面,而且w(u,v)<v.key,更新v.key=w(u,v),記錄v.parent=u

初始的圖以下

選取節點s in S,其它的爲V-S 按照初始化的規則獲得

Q:{S.key=0,A.key=\infty,B.key=\infty,C.key=\infty,D.key=\infty,E.key=\infty,F.key=\infty,G.key=\infty}

而後獲取最小key的節點,顯然他就是S

獲取S的全部鄰接表,比較crossing cut的邊的權值和當前Q中存儲的key的大小,保留小的,獲得

Q:{A.key=7,B.key=\infty,C.key=15,D.key=10,E.key=\infty,F.key=\infty,G.key=\infty}

再找到Q中最小的爲A,將二者記下來

再查看全部S的鄰接表,更新Q的權值,獲得

Q:{B.key=9,C.key=15,D.key=10,E.key=\infty,F.key=5,G.key=12}

獲取最小值爲5,將它放入S中


再次更新Q獲得

Q:{B.key=9,C.key=15,D.key=8,E.key=14,G.key=6}

獲取最小是爲6,獲得

再更新Q

Q:{B.key=9,C.key=15,D.key=8,E.key=14}

最小值爲8

更新Q獲得

Q:{B.key=9,C.key=15,E.key=3}

最小值爲3

更新Q獲得

Q:{B.key=9,C.key=15}

最小值爲9

更新Q獲得

Q:{C.key=15}

最小值爲15

最終獲得MST爲

運行時間

在整個過程當中,涉及V次的從優先級隊列中獲取最小值,以及邊兩倍次的減小key的值,因此總的時間爲

O(V)T_{extractMin}+O(E)T_{decreaseKey}

使用斐波那契堆能夠達到VlgV+E

Kruskal's算法

核心思想:全局最小的corssing cut邊一定屬於最小生成樹,這個過程不能生成環,須要追蹤兩個節點是否已經互相鏈接了

追蹤的數據結構是 Union-Find 結構,包含3個功能,Make-Set:建立一個集合;Find-Set:找到當前元素在那個集合;Union:合併集合

  • 剛開始的時候T什麼都沒有
  • 對每一個節點v都執行一遍Make-Set
  • 爲了找到全局最小的crossing cut,對整個的邊經過權值按照遞增來排序
  • 按照增序遍歷全部的邊,若是兩個節點u和v屬於不一樣的集合(crossing cut),那麼能夠合併邊T=TU{e},而後將這兩個集合合併Union(u,v)

延伸閱讀 Union-Find數據結構Ackermann函數

時間分析

T_{sort}(E)+O(V)*T_{make-set}+O(E)(T_{Find}+T_{Union})

在使用Union-Find數據結構的基礎上可以作到時間爲O(ElgE+Eα(V)),假設權重爲正整數並且最大值是個常量,那麼排序能夠達到常量的時間,這個時候,算法所須要的時間就是O(E),總體不Prims算法要好

最快的MST 算法運行指望時間是O(V+E),Karger, Klein, and Tarjan 1993發明

相關文章
相關標籤/搜索