最小生成樹

2021-10-01 14:19:06 字數 1489 閱讀 6134

假定有乙個連通無向圖g=(v,e)和權重函式,我們希望找出圖g的一顆最小生成樹,kruskal和prim演算法都是使用貪心策略來解決這個問題,但它們使用貪心策略的方式卻有所不同。

這個貪心策略可以由下面的通用方法來表述。該通用方法在每個時刻生長最小生成樹的一條邊,並在整個策略的實施過程中,管理乙個遵守下述迴圈不變式的邊集合a:

在每遍迴圈之前,a是某棵樹最小生成樹的乙個子集。

在每一步,我們要做的事情是選擇一條邊(u,v),將其加入到集合a中,使得a不違反迴圈不變式,即也是某棵最小生成樹的子集。由於我們可以安全地將這種邊加入到集合a而不破壞a的迴圈不變式,因此稱這樣的邊為集合a的安全邊。

使用迴圈不變式的方式如下:

初始化:在演算法第1行之後,集合a直接滿足迴圈不變式。

保持:演算法2-4行的迴圈通過只加入安全邊來維持迴圈不變式。

終止:所有加入到集合a中的邊都屬於某顆最小生成樹,因此,演算法第5行返回的集合a必然是一顆最小生成樹。

kruaskal演算法找到安全邊的方法是,在所有連線森林中兩顆不同樹的邊裡面,找到權重最小的邊(u,v)。

與kruskal演算法類似,prim演算法也是通用最小生成樹的乙個特例。prim演算法的工作原理與dijkstra的最短路徑演算法相似。prim演算法所具有的乙個性質是集合a中邊總是構成一棵樹。這顆樹從乙個任意的根節點r開始,一直長大到覆蓋v中的所有結點時為止。演算法每一步在連線集合a和a之外的節點所有邊中,選擇一條輕量級邊加入到a中。這條規則所加入的邊都是對a安全的邊。因此,當演算法終止時,a中的邊形成一棵最小生成樹。本策略也屬於貪心策略,因為每一步加入的邊都必須是使樹的總權重增加量最小的邊。

為了有效實現prim演算法,需要一種快速的方法來選擇一條新的邊,以便加入到由集合a中邊所構成的樹里。上面的偽**中,連通圖g和最小生成樹的根節點r將作為演算法的輸入。在演算法的執行過程中,所有不在樹a中的結點都存放在乙個基於key屬性的最小優先佇列q中。對於每個節點v,屬性v.key儲存的是連線v和樹中節點的所有邊中最小邊的權重。我們規定如果不存在這樣的邊,則。屬性給出的是節點v在樹中的父節點prim演算法將generic-mst中的結合a維持在的狀態下。

當prim演算法終止時,最小優先佇列q將為空,而g的最小生成樹a則是:

最小生成樹 次小生成樹

一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...

最小生成樹

package 圖 最小生成樹是用最少的邊吧把所有的節點連線起來。於是和圖的深度優先搜素差不多。class stack public void push int key public int pop 檢視棧頂的元素 public int peek public boolean isempty cla...

最小生成樹

define max vertex num 20 最大頂點數 typedef int adjmatrix max vertex num max vertex num 鄰接矩陣型別 typedef char vertextype typedef struct mgraph struct dnodecl...