1. 程式人生 > >資料結構 第16講 溝通無限校園網——最小生成樹(prim演算法)

資料結構 第16講 溝通無限校園網——最小生成樹(prim演算法)

本內容來源於本人著作《趣學演算法》,線上章節:http://www.epubit.com.cn/book/details/4825

校園網是為學校師生提供資源共享、資訊交流和協同工作的計算機網路。校園網是一個寬頻、具有互動功能和專業性很強的區域網絡。如果一所學校包括多個學院及部門,也可以形成多個區域網絡,並通過有線或無線方式連線起來。原來的網路系統只侷限於以學院、圖書館為單位的區域網,不能形成集中管理以及各種資源的共享,個別學院還遠離大學本部,這些情況嚴重地阻礙了整個學校的網路化需求。現在需要設計網路電纜佈線,將各個單位的區域網絡連通起來,如何設計能夠使費用最少呢?

圖2-58 校園網路

2.7.1 問題分析

某學校下設10個學院,3個研究所,1個大型圖書館,4個實驗室。其中,1~10號節點代表10個學院,11~13號節點代表3個研究所,14號節點代表圖書館,15~18號節點代表4個實驗室。該問題用無向連通圖=(VE)來表示通訊網路,V表示頂點集,E表示邊集。把各個單位抽象為圖中的頂點,頂點與頂點之間的邊表示單位之間的通訊網路,邊的權值表示佈線的費用。如果兩個節點之間沒有連線,代表這兩個單位之間不能佈線,費用為無窮大。如圖2-59所示。

圖2-59 校園網連通圖

那麼我們如何設計網路電纜佈線,將各個單位連通起來,並且費用最少呢?

對於n

個頂點的連通圖,只需n−1條邊就可以使這個圖連通,n−1條邊要想保證圖連通,就必須不含迴路,所以我們只需要找出n−1條權值最小且無迴路的邊即可。

需要說明幾個概念。

(1)子圖:從原圖中選中一些頂點和邊組成的圖,稱為原圖的子圖。

(2)生成子圖:選中一些邊和所有頂點組成的圖,稱為原圖的生成子圖。

(3)生成樹:如果生成子圖恰好是一棵樹,則稱為生成樹。

(4)最小生成樹:權值之和最小的生成樹,則稱為最小生成樹。

本題就是最小生成樹求解問題。

2.7.2 演算法設計

找出n−1條權值最小的邊很容易,那麼怎麼保證無迴路呢?

如果在一個圖中深度搜索或廣度搜索有沒有迴路,是一件繁重的工作。有一個很好的辦法——避圈法

。在生成樹的過程中,我們把已經在生成樹中的結點看作一個集合,把剩下的結點看作另一個集合,從連線兩個集合的邊中選擇一條權值最小的邊即可。

首先任選一個結點,例如1號結點,把它放在集合U中,U={1},那麼剩下的結點即VU={2,3,4,5,6,7},V是圖的所有頂點集合。如圖2-60所示。

..\17-0245 圖\0268.tif

圖2-60 最小生成樹求解過程

現在只需在連線兩個集合(VVU)的邊中看哪一條邊權值最小,把權值最小的邊關聯的結點加入到集合U。從圖2-68可以看出,連線兩個集合的3條邊中,結點1到結點2的邊權值最小,選中此條邊,把2號結點加入U集合U={1,2},VU={3,4,5,6,7}。

再從連線兩個集合(VVU)的邊中選擇一條權值最小的邊。從圖2-61可以看出,連線兩個集合的4條邊中,結點2到結點7的邊權值最小,選中此條邊,把7號結點加入U集合U={1,2,7},VU={3,4,5,6}。

圖2-61 最小生成樹求解過程

如此下去,直到U=V結束,選中的邊和所有的結點組成的圖就是最小生成樹。

是不是非常簡單啊?

這就是Prim演算法,1957年由美國電腦科學家Robert C.Prim發現的。那麼如何用演算法來實現呢?

首先,令U={u0},u0VTE={}。u0可以是任何一個結點,因為最小生成樹包含所有結點,所以從哪個結點出發都可以得到最小生成樹,不影響最終結果。TE為選中的邊集。

然後,做如下貪心選擇:選取連線UVU的所有邊中的最短邊,即滿足條件iUjVU,且邊(ij)是連線UVU的所有邊中的最短邊,即該邊的權值最小。

然後,將頂點j加入集合U,邊(ij)加入TE。繼續上面的貪心選擇一直進行到U=V為止,此時,選取到的所有邊恰好構成圖G的一棵最小生成樹T

演算法設計及步驟如下。

步驟1:確定合適的資料結構。設定帶權鄰接矩陣C儲存圖G,如果圖G中存在邊(ux),令C[u][x]等於邊(ux)上的權值,否則,C[u][x]=∞;bool陣列s[],如果s[i]=true,說明頂點i已加入集合U

如圖2-62所示,直觀地看圖很容易找出 集合到 VU集合的邊中哪條邊是最小的,但是程式中如果窮舉這些邊,再找最小值就太麻煩了,那怎麼辦呢?

..\17-0245 圖\0270.tif

圖2-62 最小生成樹求解過程

可以通過設定兩個陣列巧妙地解決這個問題,closest[j]表示VU中的頂點j到集合U中的最鄰近點,lowcost[j]表示VU中的頂點j到集合U中的最鄰近點的邊值,即邊(j,closest[j])的權值。

例如,在圖2-62中,7號結點到U集合中的最鄰近點是2,closest[7]=2,如圖2-63所示。7號結點到最鄰近點2的邊值為1,即邊(2,7)的權值,記為lowcost[7]=1,如圖2-64所示。

圖2-63 closest[]陣列

圖2-64 lowcost[]陣列

只需要在VU集合中找lowcost[]值最小的頂點即可。

步驟2:初始化。令集合U={u0},u0V,並初始化陣列closest[]、lowcost[]和s[]。

步驟3:在VU集合中找lowcost值最小的頂點t,即lowcost[t]=min{lowcost[j]|jVU},滿足該公式的頂點t就是集合VU中連線集合U的最鄰近點。

步驟4:將頂點t加入集合U

步驟5:如果集合VU為空,演算法結束,否則,轉步驟6。

步驟6:對集合VU中的所有頂點j,更新其lowcost[]和closest[]。更新公式:if(C[t] [j]<lowcost [j] ) { lowcost [j]= C [t] [j]; closest [j] = t; },轉步驟3。

按照上述步驟,最終可以得到一棵權值之和最小的生成樹。

2.7.3 完美圖解

=(VE)是無向連通帶權圖,如圖2-65所示。

圖2-65 無向連通帶權圖G

(1)資料結構

設定地圖的帶權鄰接矩陣為C[][],即如果從頂點i到頂點j有邊,就讓C[i][j]=<ij>的權值,否則C[i][j]=∞(無窮大),如圖2-66所示。

圖2-66 鄰接矩陣C[ ][ ]

(2)初始化

假設u0=1;令集合U={1},VU={2,3,4,5,6,7},TE={},s[1]=true,初始化陣列closest[]:除了1號結點外其餘結點均為1,表示VU中的頂點到集合U的最臨近點均為1,如圖2-67所示。lowcost[]:1號結點到VU中的頂點的邊值,即讀取鄰接矩陣第1行,如圖2-68所示。

圖2-67 closest[]陣列

圖2-68 lowcost[]陣列

初始化後如圖2-69所示。

..\17-0245 圖\0277.tif

圖2-69 最小生成樹求解過程

(3)找最小

在集合VU={2,3,4,5,6,7}中,依照貪心策略尋找VU集合中lowcost最小的頂點t,如圖2-70所示。

圖2-70 lowcost[]陣列

找到最小值為23,對應的結點t=2。

選中的邊和結點如圖2-71所示。

圖2-71 最小生成樹求解過程

(4)加入U戰隊

將頂點t加入集合U={1,2},同時更新VU={3,4,5,6,7}。

(5)更新

剛剛找到了到U集合的最鄰近點= 2,那麼對t在集合VU中每一個鄰接點j,都可以藉助t更新。我們從圖或鄰接矩陣可以看出,2號結點的鄰接點是3和7號結點:

C[2][3]=20<lowcost[3]=∞,更新最鄰近距離lowcost[3]=20,最鄰近點closest[3]=2;

C[2][7]=1<lowcost[7]=36,更新最鄰近距離lowcost[7]=1,最鄰近點closest[7]=2;

更新後的closest[j]和lowcost[j]陣列如圖2-72和圖2-73所示。

圖2-72 closest[]陣列

圖2-73 lowcost[]陣列

更新後如圖2-74所示。

..\17-0245 圖\0282.tif

圖2-74 最小生成樹求解過程

closest[j]和lowcost[j]分別表示VU集合中頂點jU集合的最鄰近頂點和最鄰近距離。3號頂點到U集合的最鄰近點為2,最鄰近距離為20;4、5號頂點到U集合的最鄰近點仍為初始化狀態1,最鄰近距離為∞;6號頂點到U集合的最鄰近點為1,最鄰近距離為28;7號頂點到U集合的最鄰近點為2,最鄰近距離為1。

(6)找最小

在集合VU={3,4,5,6,7}中,依照貪心策略尋找VU集合中lowcost最小的頂點t,如圖2-75所示。

..\17-0245 圖\0283.tif

圖2-75 lowcost[]陣列

找到最小值為1,對應的結點t=7。

選中的邊和結點如圖2-76所示。

圖2-76 最小生成樹求解過程

(7)加入U戰隊

將頂點t加入集合U={1,2,7},同時更新VU={3,4,5,6}。

(8)更新

剛剛找到了到U集合的最鄰近點t =7,那麼對t在集合VU中每一個鄰接點j,都可以借t更新。我們從圖或鄰接矩陣可以看出,7號結點在集合VU中的鄰接點是3、4、5、6結點:

C[7][3]=4<lowcost[3]=20,更新最鄰近距離lowcost[3]=4,最鄰近點closest[3]=7;

C[7][4]=9<lowcost[4]=∞,更新最鄰近距離lowcost[4]=9,最鄰近點closest[4]=7;

C[7][5]=16<lowcost[5]=∞,更新最鄰近距離lowcost[5]=16,最鄰近點closest[5]=7;

C[7][6]=25<lowcost[6]=28,更新最鄰近距離lowcost[6]=25,最鄰近點closest[6]=7;

更新後的closest[j]和lowcost[j]陣列如圖2-77和圖2-78所示。

圖2-77 closest[]陣列

圖2-78 lowcost[]陣列

更新後如圖2-79所示。

..\17-0245 圖\0287.tif

圖2-79 最小生成樹求解過程

closest[j]和lowcost[j]分別表示VU集合中頂點jU集合的最鄰近頂點和最鄰近距離。3號頂點到U集合的最鄰近點為7,最鄰近距離為4;4號頂點到U集合的最鄰近點為7,最鄰近距離為9;5號頂點到U集合的最鄰近點為7,最鄰近距離為16;6號頂點到U集合的最鄰近點為7,最鄰近距離為25。

(9)找最小

在集合VU={3,4,5,6}中,依照貪心策略尋找VU集合中lowcost最小的頂點t,如圖2-80所示。

..\17-0245 圖\0288.tif

圖2-80 lowcost[]陣列

找到最小值為4,對應的結點t=3。

選中的邊和結點如圖2-81所示。

圖2-81 最小生成樹求解過程

(10)加入U戰隊

將頂點t加入集合U ={1,2,3,7},同時更新VU={4,5,6}。

(11)更新

剛剛找到了到U集合的最鄰近點t =3,那麼對t在集合VU中每一個鄰接點j,都可以藉助t更新。我們從圖或鄰接矩陣可以看出,3號結點在集合VU中的鄰接點是4號結點:

C[3][4]=15>lowcost[4]=9,不更新。

closest[j]和lowcost[j]陣列不改變。

更新後如圖2-82所示。

..\17-0245 圖\0290.tif

相關推薦

資料結構 16 溝通無限校園網——小生成樹prim演算法

本內容來源於本人著作《趣學演算法》,線上章節:http://www.epubit.com.cn/book/details/4825 校園網是為學校師生提供資源共享、資訊交流和協同工作的計算機網路。校園網是一個寬頻、具有互動功能和專業性很強的區域網絡。如果一所學校包括多個學院及部門,也可

資料結構 17 溝通無限校園網——小生成樹kruskal演算法

本內容來源於本人著作《趣學演算法》,線上章節:http://www.epubit.com.cn/book/details/4825 構造最小生成樹還有一種演算法,Kruskal演算法:設G=(V,E)是無向連通帶權圖,V={1

資料結構實驗之圖論九:小生成樹 SDUT 2144

#include<bits/stdc++.h> using namespace std; typedef long long ll; struct node { int s, e; int w; }s[100005]; int c[105]; bool cmp(str

資料結構——四章圖:04小生成樹

1.(連通網的)最小生成樹問題提出:假設要在n個城市之間建立通訊聯絡網,則連通n個城市只需要修建n-1條線路,如果在最節省經費的前提下建立這個通訊網?該問題等價於:構造網的一棵最小生成樹,即:在e條帶權的邊中選取n-1條邊(不構成迴路),使權值之和為最小。有兩種演算法:Prim(普利姆)演算法和Kruskal

NYOJ - 溝通無限校園網(小生成樹)

題目連結:http://nyoj.top/problem/1403 記憶體限制:64MB 時間限制:1000ms 題目描述: 校園網是為學校師生提供資源共享、資訊交流和協同工作的計算機網路。校園網是一個寬頻、具有互動功能和專業性很強的區域網絡。如果一所學校包括多個

資料結構 筆記:小生成樹prim

運營商的挑戰 -在下圖標出的城市間架設一條通訊線路 要求: ·任意兩個城市間都能夠通訊 ·將架設成本呢將至最低   如何在圖中選擇n-1條邊使得n個頂點間兩兩可達,並且這n-1條邊的權值之和最小 最小生成樹 -僅使用圖中的n-1條邊連線圖中的n個頂點

資料結構實驗之圖論九:小生成樹__Prim

Problem Description 有n個城市,其中有些城市之間可以修建公路,修建不同的公路費用是不同的。現在我們想知道,最少花多少錢修公路可以將所有的城市連在一起,使在任意一城市出發,可以到達其他任意的城市。 Input 輸入包含多組資料,格式如下。 第一行包括兩個整數n m,

c++資料結構演算法之圖:鄰接矩陣、深度廣度遍歷、構造小生成樹prim、kruskal演算法

//圖的鄰接矩陣實現 //廣度遍歷bfs和深度遍歷dfs //構造最小生成樹的prim、kruskal演算法 #include <iostream> #include<stack> #include<queue> #define WEI

資料結構 14 神祕電報密碼——哈夫曼編碼

本文來源於本人著作《趣學演算法》。 看過諜戰電影《風聲》的觀眾都會對影片中神奇的訊息傳遞驚歎不已!吳志國大隊長在受了殘忍的“針刑”之後躺在手術檯上唱空城計,變了音調,把訊息傳給了護士,顧曉夢在衣服上縫補了長短不一的針腳……那麼,片中無處不在的摩爾斯碼到底是什麼?它又有著怎樣的神祕

16 章 C 預處理器和 C 庫條件編譯

struct FN getc con ade 定義 輸入 lap pla 1 /*-------------------------------------- 2 names_st.h -- names_st 結構的頭文件 3 --------------

資料結構】二叉樹的建立與遍歷遞迴

該程式全是使用遞迴的操作 執行環境是:Dev-C++ #include <stdio.h> #include <stdlib.h> typedef struct node{ char data; struct node *lchild,*rchild; }bi

資料結構實驗之棧與佇列四:括號匹配SDUT 2134

#include <bits/stdc++.h> using namespace std; typedef long long ll; char s[100]; char a[100]; int main() { int i,j,k,f,top,len; while(

資料結構——圖8——小生成樹MST

問題的提出 如下圖,假設這裡有一系列的房屋,問如何鋪設電線,可以使得連線所有房屋的電線的總成本最低?這是20世紀20年代早期研究最小生長樹的最初動機。 (捷克數學家OtakarBorůvka完成的工作)。 最短路徑樹與最小生成樹(MST) 上次,我們看到了Dijkstra演

資料結構實現 5.1:對映_基於樹實現C++版

資料結構實現 5.1:對映_基於樹實現(C++版) 1. 概念及基本框架 2. 基本操作程式實現 2.1 增加操作 2.2 刪除操作 2.3 修改操作 2.4 查詢操作 2.5 其他操作 3. 演算法複

資料結構實驗之二叉樹七:葉子問題SDUT 3346

#include <bits/stdc++.h> using namespace std; struct node { char data; struct node *lc, *rc; }; char a[100]; int num = 0; struct node

資料結構 筆記:小生成樹Kruskal

最小生成樹的特徵: -選取的邊是圖中權值較小的邊 -所有邊連線後不構成迴路 既然最小生成樹關心的是如何選擇n-1條邊,那麼是否可以直接以邊為核心進行演算法設計? -由4個頂點構成圖,選擇3條權值最小的邊 如何判斷新選擇的邊與已選擇的邊是否構成迴路? 技巧:前驅標記陣列 -

小生成樹資料結構

最小生成樹-Prim演算法和Kruskal演算法   Prim演算法 1.概覽 普里姆演算法(Prim演算法),圖論中的一種演算法,可在加權連通圖裡搜尋最小生成樹。意即由此演算法搜尋到的邊子集所構成的樹中,不但包括了連

中國大學MOOC-陳越、何欽銘-資料結構-2018秋 03-樹1 樹的同構 25 分

給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。 圖1 圖2 現給定兩棵樹,請你判

浙大版《資料結構》習題4.3 是否二叉搜尋樹 25 分

本題要求實現函式,判斷給定二叉樹是否二叉搜尋樹。 函式介面定義: bool IsBST ( BinTree T ); 其中BinTree結構定義如下: typedef struct TNode *Position; typedef Position BinT

資料結構實驗之查詢一:二叉排序樹 SDUT 3373

二叉排序樹(Binary Sort Tree),又稱二叉查詢樹(Binary Search Tree),也稱二叉搜尋樹。 #include <stdio.h> #include <string.h> #include <stdlib.h> struct nod