最小生成樹--Prim演算法
阿新 • • 發佈:2019-01-10
最近研究圖論的演算法,接觸到構建最小生成樹的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