1. 程式人生 > >最小生成樹--Prim演算法

最小生成樹--Prim演算法

最近研究圖論的演算法,接觸到構建最小生成樹的prim演算法(當然還有其他方法:Kruskal演算法也可以構建),所以記錄一下。
首先,什麼是最小生成樹?
百度百科給出的定義:一個有 n 個結點的連通圖的生成樹是原圖的極小連通子圖,且包含原圖中的所有 n 個結點,並且有保持圖連通的最少的邊。
概念有點抽象,下面用一幅圖來演示說明。
這裡寫圖片描述

那麼如何構建一棵最小生成樹呢?有下面三個步驟:
1).輸入:一個加權連通圖,其中頂點集合為V,邊集合為E;
2).初始化:U={x},其中x為集合V中的任一節點(起始點),T={},為空;
3).重複下列操作,直到U=V:

    a、在集合E中選取全值最小的邊<u,v
>
,其中u為集合U中的元素,而v不在U集合裡面, 並且v屬於V(如果存在多條滿足前述條件,即具有相同權值的邊,則可以任意選取其中之一); b、將v加入集合U中,將<u,v>邊加入集合T中;

4).輸出:使用集合U和T,來描述所得到的最小生成樹。

下面用圖來展示上面給出的步驟:

這裡寫圖片描述

程式碼如下:

/**
* prim最小生成樹
*/
public  void prim(){
char[] code={'A','B','C','D','E','F','G'};
 ArrayList<Integer> u =new ArrayList<>();
 //預設A是第一個節點
u.add(3); //T{} ArrayList<int[]> t =new ArrayList<>(); //重複直到U=T while(u.size()!=this.verticeSize){ int tmp=BGraph.MAXVERTICESIZE; int tmpi=0; int pi=0,pj=0; //找最短距離 for (int i = 0; i < u.size(); i++) { tmpi=u.get(i); for (int j = 0; j < this.verticeSize; j++) { if
(this.verticesEde[tmpi][j]!=0&&this.verticesEde[tmpi][j]<tmp){ tmp=this.verticesEde[tmpi][j]; pi=tmpi; pj=j; } } } if(tmp!=BGraph.MAXVERTICESIZE){ //找到最短距離 t.add(new int[]{pi,pj,verticesEde[pi][pj]}); u.add(pj); //代表已經訪問過 this.verticesEde[pi][pj]=0; this.verticesEde[pj][pi]=0; } } int sum=0; for (int i = 0; i < t.size(); i++) { int[] nums=t.get(i); sum+=nums[2]; System.out.println(code[nums[0]]+" -> "+code[nums[1]]); } System.out.println("最小生成樹總代價:"+sum); } //測試程式碼 Graph graph=new Graph(7); int[] a0={0,50,60,MAXVERTICESIZE,MAXVERTICESIZE,MAXVERTICESIZE,MAXVERTICESIZE}; int[] a1={50,0,MAXVERTICESIZE,65,40,MAXVERTICESIZE,MAXVERTICESIZE}; int[] a2={60,MAXVERTICESIZE,0,52,MAXVERTICESIZE,MAXVERTICESIZE,45}; int[] a3={MAXVERTICESIZE,65,52,0,50,30,42}; int[] a4={MAXVERTICESIZE,40,MAXVERTICESIZE,50,0,70,MAXVERTICESIZE}; int[] a5={MAXVERTICESIZE,MAXVERTICESIZE,MAXVERTICESIZE,30,70,0,MAXVERTICESIZE}; int[] a6={MAXVERTICESIZE,MAXVERTICESIZE,45,42,MAXVERTICESIZE,MAXVERTICESIZE,0}; graph.verticesEde[0]=a0; graph.verticesEde[1]=a1; graph.verticesEde[2]=a2; graph.verticesEde[3]=a3; graph.verticesEde[4]=a4; graph.verticesEde[5]=a5; graph.verticesEde[6]=a6; graph.prim(); 執行結果: A -> B B -> E E -> D D -> F D -> G G -> C 最小生成樹總代價:257