图论(八)最小生成树
一個正在進行信息化建設的國家級貧困縣,需要在下屬9個鄉鎮之間架設光纖網絡。為減少建設難度,光纖網主要沿著這9個鄉鎮之間互連的公路進行鋪設。這9個鄉鎮之間的公路網以及相互之間的距離(單位:km)如下圖所示:
如果你是工程師,該怎樣設計線路鋪設方案?當然,你可以直接把所有的公路網都鋪設上光纜,這樣的線路總長度是247公里。但如果你是這樣想的,那么我一定會懷疑你到底是不是一名工程師!
你可以再設計一種方案,如下圖中粗線條所示:
這種鋪設方案的線路總長是161公里,這比前面的強多了。再進一步,你還可以得到2種更短的鋪設線路:
這2種線路的總長分別是100km和95km。顯然比前面的方案節省了更多。當然,這種線路方案你還可以列出很多。
在這個實際應用中,我們的目的,是要尋求一種連接圖中所有節點的、成本最低的方式。本質上,再抽象一層,這是個組合優化問題,可以使用一些智能優化算法來解決。而在這個實例上,我們尋求使用更簡單的圖論方式解決。
當然,這是個老問題了,至少在20世紀初就已經提出了,它的解決方案最初是1926年由捷克數學家在構建一個電力網絡的過程中首先提出來的。這種方式經常被用于架設電網、通信網、公路網、鐵路網,甚至是架構某種形式的計算集群(這些任務都需要我們連接其中的每一個節點),也是解決旅行商問題的基礎。
再回到這個問題本身,要包含圖中所有的頂點n,同時代價最少,第一個想到的自然是減少邊的數量,而要連接所有n個頂點,顯然至少需要n-1條邊。而我們知道一顆樹(tree)就是n個頂點,n-1條邊。
所以,這里引申出圖論中的一個新概念:生成樹(spanning tree)。含有圖中全部n個頂點,以及包含圖中某些n-1條邊的一顆樹是該圖的生成樹。有幾個情況需要注意:
- 圖本身必須是無向連通圖;
如果是非連通圖,那就不存在生成樹的概念。我們知道樹中任意2點都是連通的。如果是有向圖,那也沒有這個概念。 - 生成樹不止一種;
生成樹的n-1條邊可以在圖的邊集合中選擇,當然不止一種情況。 - 每個生成樹代價不同。
一般使用生成樹中邊的權重值總和代表每個生成樹的代價。
而我們的工作就是要找到所有生成樹中代價最小的,這就是最小生成樹(minimum spanning tree)問題。
那么,我們構建最小生成樹的時候,要從哪里著手呢?
首先,我們從邊出發,先找到最短的邊。
如上圖所示,邊e-i顯然是最短的。最小生成樹會不會一定包含這條邊?根據上面的描述,生成樹要包含所有的頂點,因此,生成樹一定包含e,i兩個頂點,所以也必然包含一條e,i之間的路徑。我們隨便構成一個生成樹,見下圖:
圖中粗線條為構成的生成樹,并不包含最短邊e-i。e,i之間的路徑是e-f-j-d-b-a-i,如果我們將邊e-i加入這個生成樹,必然構成環。
要消除這個環,從而構成新的生成樹,我們可以移除e-f-j-d-b-a-i-e環路上除邊e-i的其他任意一條邊。例如,移除a-b或b-d。我們看看移除b-d,構成了一個新的生成樹。
這個新的生成樹與原先的生成樹就差在一個包含邊b-d,不包含邊e-i,一個包含邊e-i,不包含b-d。而新的生成樹代價比原先的生成樹代價低,因為邊e-i是最短的,代價比邊b-d要小。
因此,無論移除其他邊中的哪條邊,重新構成新的生成樹都比最先的生成樹代價小。因為哪條邊的代價都比邊e-i的代價要大。也就是說,任何不包含最短邊的生成樹結構都可以被做的更小。所以,最小生成樹一定包含最短邊。(后面的文章我們將看到,這也是最小生成樹算法Kruskal的基本思想)。
其次,我們從頂點出發,來看看有什么新的結論。還是上面的圖,我們以頂點b為例,根據生成樹的定義,頂點b與其它頂點肯定是連通的。而頂點b有2條邊,即邊a-b,邊b-d。這意味著最小生成樹必然包含這2條邊中的一個。而邊b-d比a-b要短,因此選擇b-d是否更合理?
我們用反證法證明下,假設選擇較長的邊a-b是更好的選擇,即最小生成樹包含a-b這條邊。我們把邊b-d也加入這個生成樹,形成了一個環。在這個環中,如果移除邊a-b,那么得到的新生成樹代價比以前的要小,這與假設的選擇較長邊更好相矛盾。所以在b點選擇較短的邊才有可能生成最小生成樹。(后面的文章我們將看到,這也是最小生成樹算法Prim的基本思想)。
參考文獻:
1.《大話數據結構》 程杰 清華大學出版社
2.《Python算法教程》Magnus Lie Hetland 人民郵電出版社
總結
以上是生活随笔為你收集整理的图论(八)最小生成树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 高考与机器学习训练测试
- 下一篇: 图论(九)最小生成树-Kruskal算法