a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C > 正文

Prim(普里姆)算法求最小生成樹的思想及C語言實例講解

2020-01-26 14:32:04
字體:
來源:轉載
供稿:網友

Prim 算法思想:
從任意一頂點 v0 開始選擇其最近頂點 v1 構成樹 T1,再連接與 T1 最近頂點 v2 構成樹 T2, 如此重復直到所有頂點均在所構成樹中為止。
最小生成樹(MST):權值最小的生成樹。
生成樹和最小生成樹的應用:要連通n個城市需要n-1條邊線路。可以把邊上的權值解釋為線路的造價。則最小生成樹表示使其造價最小的生成樹。
構造網的最小生成樹必須解決下面兩個問題:
1、盡可能選取權值小的邊,但不能構成回路;
2、選取n-1條恰當的邊以連通n個頂點;
MST性質:假設G=(V,E)是一個連通網,U是頂點V的一個非空子集。若(u,v)是一條具有最小權值的邊,其中u∈U,v∈V-U,則必存在一棵包含邊(u,v)的最小生成樹。
prim算法假設G=(V,E)是連通的,TE是G上最小生成樹中邊的集合。算法從U={u0}(u0∈V)、TE={}開始。重復執行下列操作:
在所有u∈U,v∈V-U的邊(u,v)∈E中找一條權值最小的邊(u0,v0)并入集合TE中,同時v0并入U,直到V=U為止。
此時,TE中必有n-1條邊,T=(V,TE)為G的最小生成樹。
 Prim算法的核心:始終保持TE中的邊集構成一棵生成樹。
注意:prim算法適合稠密圖,其時間復雜度為O(n^2),其時間復雜度與邊得數目無關,而kruskal算法的時間復雜度為O(eloge)跟邊的數目有關,適合稀疏圖。
舉個簡單的例子來說明具體的實現方法:

2016626160439131.jpg (361×256)

G:圖,用鄰接矩陣表示
vcount:表示圖的頂點個數
max_vertexes:圖最大節點數
infinity:為無窮大
數組存儲從0開始
由于最小生成樹包含每個頂點,那么頂點的選中與否就可以直接用一個數組來標記used[max_vertexes];(我們這里直接使用程序代碼中的變量定義,這樣也易于理解);當選中一個數組的時候那么就標記,現在就有一個問題,怎么來選擇最小權值邊,注意這里最小權值邊是有限制的,邊的一個頂點一定在已選頂點中,另一個頂點當然就是在未選頂點集合中了。我最初的一個想法就是窮搜了,就是在一個集合中選擇一個頂點,來查找到另一個集合中的最小值,這樣雖然很易于理解,但是很明顯效率不是很高,在嚴蔚敏的《數據結構》上提供了一種比較好的方法來解決:設置兩個輔助數組lowcost[max_vertexes]和closeset[max_vertexes],lowcost[max_vertexes]數組記錄從U到V-U具有最小代價的邊。對于每個頂點v∈V-U,closedge[v], closeset[max_vertexes]記錄了該邊依附的在U中的頂點。

Prim 算法步驟:
T0 存放生成樹的邊,初值為空
輸入加權圖的帶權鄰接矩陣 C = (Cij)n×n (兩點間無邊相連則其大小為無窮)
為每個頂點 v 添加一屬性 L(v) :表 v 到 T0 的最小直接距離
(1) T0←∅, V1={v0}, C(T0)=0
(2) 對任意v ∈ V,L(v)←C(v, v0)
(3) If V==V1 then stop else goto next.
(4) 在 V-V1 中找點 u 使 L(u) =min{ L(v) | v ∈ (V − V1 )},記 V1 中與 u 相鄰點為 w.
(5) T0←T0∪{(u, w)}, C(T0) ←C(T0)+C(u, w), V1←V1∪{u}
(6) 對任意v ∈ (V − V1 ) if C(v, u)<L(v) then L(v) = C(v, u) else L(v)不變。
(7) Go to 3.

C++實現示例
prim.txt中的內容:

1 2 61 3 11 4 52 3 52 5 33 4 53 5 63 6 45 6 64 6 2

 
程序代碼:

#include<stdo.h>#include<string.h>#include <stdlib.h> #define infinity 1000000 //  定義兩個不直接相鄰一步到達頂點的距離 #define max_vertexes 6 //  定義圖形中頂點的個數 typedef int Graph[max_vertexes][max_vertexes];// 邊上的權值 void prim(Graph G,int vcount,int father[]){    int i,j,k;  int lowcost[max_vertexes];//最小代價邊上的權值  int closeset[max_vertexes],used[max_vertexes];//依附在U中的頂點;標記是否已被選中  int min;  int result=0;//記錄最短距離權值的和    for (i=0;i<vcoun;k++)  //初始化所有數組,把最短距離初始化為其他頂點到1結點的距離  {      lowcost[i]=G[0][i];       closeset[i]=0;      used[i]=0;     father[i]=-1;     }    used[0]=1;      for (i=1;i<=vcount-1;i++)     {      j=0;    min = infinity;         for (k=1;k<count;k++) //for循環得到離結點最近的頂點j   if ((!used[k])&&(lowcost[k]   {    min = lowcost[k];    j=k;   }   father[j]=closeset[j];    printf("%d %d/n",j+1,father[j]+1);//輸出當前找到的結點,該頂點依附的上一個結點   result=result+G[j][closeset[j]];   used[j]=1;;//把第j個頂點并入了U中     for (k=1;k           if (!used[k]&&(G[j][k]保留到k的最短路徑     {      lowcost[k]=G[j][k];         closeset[k]=j;    }     }  printf("%d",result);}        int main(){  FILE *fr;  int i,j,weight;  Graph G;  int fatheer[max_vertexes];  for(i=0; i<max_vertexes;i++)  for(j=0; j<max_vertexer;i++)  G[i][j] = infinity;  fr = fopen("prim.txt","r");  if(!fr)  {   printf("fopen failed/n");   exit(1);  }  while(fscanf(fr,"%d%d%d", &i, &j, &weight) != EOF)  {   G[i-1][j-1] = weight;   G[j-1][i-1] = weight;  }   prim(G,max_vertexes,fatheer);  return 0; }

測試的結果如下:
2016626160558508.jpg (490×297)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 欧美一区精品 | 国产亚洲欧美一区 | 欧美成人精品一区二区三区 | 久久99国产精品 | 99国产在线观看 | 欧美一区三区三区高中清蜜桃 | 日韩精品一区二区三区中文在线 | 日本福利视频网 | 欧美一区二区在线免费观看 | 精品久久久久香蕉网 | 精品国产一区二区三区久久久蜜月 | 亚洲专区国产精品 | 成人一区二区三区在线观看 | 男女免费视频 | 欧美一区二区三区四区视频 | 午夜精品久久久久久久久久久久 | 国产亚州av | 在线欧美日韩 | 视频一区二区国产 | 日韩电影免费 | 99视频免费观看 | 国产精品久久视频 | 欧美国产日韩一区 | 亚洲精品午夜电影 | 国产精品视频久久久久 | 久久草视频 | 久久久精品综合 | 日韩在线国产精品 | 日韩成人在线免费视频 | 羞羞视频网站 | 欧美在线观看一区 | 中文字幕久久精品 | 九色 在线 | 99视频这里有精品 | 污视频链接 | 亚洲人成人一区二区在线观看 | 中文字幕第一页久久 | 一区二区在线看 | 在线免费观看羞羞视频 | 二区在线观看 | 国产浪潮av色综合久久超碰 |