最小生成樹 普里姆 Prim 演算法詳解和實現

2021-10-05 21:49:34 字數 2783 閱讀 1547

普里姆演算法的基本思想是:假設連通網路為 n=(v,e);

te為n的最小生成樹上邊的集合,開始時te為空集;

u為演算法在構造最小生成樹過程中已得到的頂點集,開始時u=(u0屬於v)。

(1) 演算法從n中的某一頂點u0出發,選擇與u0關聯的具有最小權值的邊(u0,vi),將頂點vi加入到生成樹的頂點集合u中,(u0,vi)加入到集合te中;

(2) 以後每一步從乙個頂點在u中,而另乙個頂點在(v-u)中的各條邊當中選擇權值最小的邊(u,v)(u屬於u,v屬於v-u),把頂點v加入到集合u中,邊(v,u)加入到集合te中。

(3) 如此重複,直到網路中的所有頂點都加入到生成樹頂點集合u(u=v)中為止。此時,te中剛好有n-1條邊,則t=(v,te)為n的最小生成樹。

例如,對於圖7-18(a)所示的連通網路,圖7-2l(a)~(f)給出了按普里姆演算法構造最小生成樹的過程。

在利用普里姆演算法構造最小生成樹過程中,需要設定乙個輔助陣列closearc[ ],以記錄從v-u中頂點到u中頂點具有最小權值的邊。對每乙個頂點v屬於v-u,在輔助陣列中有乙個分量closearc[v],它包括兩個域:lowweight 和nearvertex。其中,lowweight中存放頂點v到u中的各頂點的邊上的當前最小權值(lowweight=0表示v屬於u);nearvertex記錄頂點v到u中具有最小權值的那條邊的另乙個鄰接頂點u(nearvertex=-1表示該頂點v為開始頂點)。

也就是說,通過 lowweight=0和 lowweight != 0將頂點分為已經在生成樹中和還未包含入生成樹中;用nearvertex記錄到達當前節點的前乙個結點,而因 為每次取權值最小,從nearvertex = -1到當前結點的nearvertex可以得到從第乙個結點到當前結點的最短路徑。

在下面的普里姆演算法描述中,連通網路採用鄰接矩陣作為儲存結構,並假設普里姆演算法從頂點a(設頂點a的序號為0)出發(即u0=0)。普里姆演算法步驟如下:

1)初始化輔助陣列closearc。

2)重複下列步驟3)和4)n-1次。

3)在closearc中選擇lowweight≠0&&lowweight最小的頂點v,即選中的權值最小的邊為(closearc[v].nearvertex,i)。將closearc[v].lowweight改為0,表示頂點i已加入頂點集u中,並將邊(closearc[v].nearvertex,v)加入生成樹t的邊集合。

4)對v-u中的每乙個頂點 j,如果依附於頂點 j 和剛加入u集合的新頂點 v 的邊的權值arcs[ v ][ j ]小於原來依附於 j 和生成樹頂點集合中頂點的邊的最短距離

closearc[ j ].lowweight,則修改 closcarc[ j ],使其lowweight=arcs[ v ][ j ],nearvertex=v。

}在普里姆演算法中,主要有兩個並列的for 迴圈。

設連通網路由n個頂點和e條邊組成,則第乙個for迴圈執行n-1次對輔助陣列closearc進行初始化;第二個for迴圈是個二重巢狀迴圈,外迴圈執行n-1次把n-1個頂點加入u中,對每加入乙個頂點到u,有兩個並列的for迴圈分別實現查詢具有最小權值的邊和修改輔助陣列closearc,它們的時間複雜度均為o(n),所以整個演算法的間複雜度為o(n^2)。

由此可見,普里姆演算法適用於邊稠密的連通網路

q:如何記錄頂點已經被選中?

a:通過構造輔助陣列lowweight以記錄已生成的結點集同剩下的各個未被選中的結點之間的最短權值。若結點已經被選中,則設定對應序號的lowweight陣列元素值為0。

q:如何記錄資訊以便於知道加入乙個結點後哪條邊的權值最小?

a:通過找出lowweight陣列中的最小值。

q:如何將權值最小的邊連線的未被選中的結點加入最小生成樹?

a:通過構造輔助陣列nearvertex以記錄每乙個被選中結點的相鄰結點,再將未被選中的結點加入最小生成樹時,修改對應序號的lowweight陣列元素值為0,修改對應序號的nearvertex陣列值為其相鄰結點。

最小生成樹 普里姆演算法 Prim

最小生成樹 的7到12行先初始化了矩陣第一行的值,本來很奇怪,那其他行的值怎麼辦?看到最後的28 35行才知道,原來從下面開始會逐步初始化與上個頂點相關的邊的值,最後能夠把全部都初始化了。截圖如下 演算法定義 1 輸入 乙個加權連通圖,其中頂點集合為v,邊集合為e 2 初始化 v new 其中x為集...

最小生成樹演算法 普里姆Prim演算法

1.鄰接矩陣儲存 cpp view plain copy 圖的鄰接矩陣儲存表示 define infinity int max define max vertex num 20 typedef enum graphkind typedef enum status typedef struct arc...

最小生成樹之Prim(普里姆)演算法

關於什麼是prim 普里姆演算法 在實際生活中,我們經常碰到類似這樣的一類問題 假設要在n個城市之間建立通訊聯絡網,則連通n個城市只需要n 1條線路。這時,我們需要考慮這樣乙個問題,如何在最節省經費前提 下建立這個通訊網.換句話說,我們需要在這n個城市中找出乙個包含所有城市的連通子圖,使得 其所有邊...