普利姆演算法
阿新 • • 發佈:2019-02-10
普里姆演算法的基本思想:普里姆演算法是一種構造最小生成樹的演算法,它是按逐個將頂點連通的方式來構造最小生成樹的。
從連通網路N = { V, E }中的某一頂點u0出發,選擇與它關聯的具有最小權值的邊(u0, v),將其頂點加入到生成樹的頂點集合U中。以後每一步從一個頂點在U中,而另一個頂點不在U中的各條邊中選擇權值最小的邊(u, v),把該邊加入到生成樹的邊集TE中,把它的頂點加入到集合U中。如此重複執行,直到網路中的所有頂點都加入到生成樹頂點集合U中為止。
假設G=(V,E)是一個具有n個頂點的帶權無向連通圖,T(U,TE)是G的最小生成樹,其中U是T的頂點集,TE是T的邊集,則構造G的最小生成樹T的步驟如下:
(1)初始狀態,TE為空,U={v0},v0∈V;
(2)在所有u∈U,v∈V-U的邊(u,v)∈E中找一條代價最小的邊(u′,v′)併入TE,同時將v′併入U;
重複執行步驟(2)n-1次,直到U=V為止。
在普里姆演算法中,為了便於在集合U和(V-U)之間選取權值最小的邊,需要設定兩個輔助陣列closest和lowcost,分別用於存放頂點的序號和邊的權值。
對於每一個頂點v∈V-U,closest[v]為U中距離v最近的一個鄰接點,即邊(v,closest[v])是在所有與頂點v相鄰、且其另一頂點j∈U的邊中具有最小權值的邊,其最小權值為lowcost[v],即lowcost[v]=cost[v][closest[v]],採用鄰接表作為儲存結構: 設定一個輔助陣列closedge[]: cost域存放生成樹頂點集合內頂點到生成樹外各頂點的各邊上的當前最小權值; adjvex域記錄生成樹頂點集合外各頂點距離集合內哪個頂點最近(即權值最小)。 應用Prim演算法構造最小生成樹的過程:
對於每一個頂點v∈V-U,closest[v]為U中距離v最近的一個鄰接點,即邊(v,closest[v])是在所有與頂點v相鄰、且其另一頂點j∈U的邊中具有最小權值的邊,其最小權值為lowcost[v],即lowcost[v]=cost[v][closest[v]],採用鄰接表作為儲存結構: 設定一個輔助陣列closedge[]: cost域存放生成樹頂點集合內頂點到生成樹外各頂點的各邊上的當前最小權值; adjvex域記錄生成樹頂點集合外各頂點距離集合內哪個頂點最近(即權值最小)。 應用Prim演算法構造最小生成樹的過程:
class Node{ int adjVex; //到該點的邊的另一頂點 int cost; //權值 public Node(int cost){ this.cost=65535; } } public class Demo { public static void main(String[] args) { int[][] graph={{65535,6,1,5,65535,65535}, {6,65535,5,65535,3,65535}, {1,5,65535,5,6,4}, {5,65535,5,65535,65535,2}, {65535,3,6,65535,65535,6}, {65535,65535,4,2,6,65535}}; MiniSpanTree(graph,6,0); } public static void MiniSpanTree(int[][] graph,int n,int u){ Node[] closedge=new Node[n]; int k; for(int i=0;i<n;i++){ //初始化 closedge[i]=new Node(65535); if(i!=u){ closedge[i].adjVex=u; closedge[i].cost=graph[u][i]; } } closedge[u].cost=0; //初始化u for(int i=1;i<n;i++){ k=min(closedge,n); System.out.println("V"+closedge[k].adjVex+",V"+k); closedge[k].cost=0; for(int j=0;j<n;j++){ //加入新頂點後重新選擇最小邊 if(graph[k][j]<closedge[j].cost){ closedge[j].adjVex=k; closedge[j].cost=graph[k][j]; } } } } public static int min(Node[] closedge,int n) { //求出下一條權值最小的邊 int k=0; int minCost=65535; for(int i=0;i<n&&closedge[i].cost==0;i++){ for(int j=0;j<n;j++){ if(closedge[j].cost!=0&&closedge[j].cost<minCost){ minCost=closedge[j].cost; k=j; } } } return k; } }