圖的普里姆(Prim)算法求最小生成樹


關於圖的最小生成樹算法------普里姆算法

首先我們先初始化一張圖:

設置兩個數據結構來分別代表我們需要存儲的數據:

lowcost[i]:表示以i為終點的邊的最小權值,當lowcost[i]=0說明以i為終點的邊的最小權值=0,也就是表示i點加入了mst數組

mst[i]:這個數組對應的下標(圖頂點)的值,是當前最小生成樹表示的頂點的連接的那個邊的權值

 

我們假設v1是初始點,進行初始化,不相連的用*表示,表示無窮大!

我們先把所有v1對應的頂點的權值放進lowcost數組中,進行初始化,之后我們取出lowcost中最小的權值:

lowcost[2]=6,lowcost[3]=1,lowcost[4]=5,lowcost[5]=*,lowcost[6]=*

mst[2]=1,mst[3]=1,mst[4]=1,mst[5]=1,mst[6]=1,(所有點默認起點是V1)

明顯看出,以V3為終點的邊的權值最小=1,所以這條邊加入mst,注意,找到最小值時(1這個值在lowcost里對應的是下標2,頂點v3),說明當前v3已經確定了他所選擇的最小權值邊(以v3為主動連接方),記得把lowcost[3]設置為0,代表已經確定的!!

此時,因為點V3的加入,需要更新lowcost數組和mst數組,為什么要這么更新?因為當從v1里面選出v3的時候,這個時候我們就從v3開始繼續規划,因為v3的對應權值數組是

v3:{1,5,0,5,6,4}

而此時lowcost數組值是:{1,6,0,5,*,*}

這時我們拿lowcost數組和v3對應的權值數組比較(下標要對應),把v3里比low里小的值替換給low數組(這么做的意義是,例如,下標為1時,v3是5,low是6,也就是說,下標為1對應的頂點是v2,v2可以選擇和v3連接(因為權值5<6),所以5會替換6),這樣得到的最終lowcost為:

lowcost[2]=5,lowcost[3]=0,lowcost[4]=5,lowcost[5]=6,lowcost[6]=4

mst[2]=3,mst[3]=0,mst[4]=1,mst[5]=3,mst[6]=3

明顯看出,以V6為終點的邊的權值最小=4,所以邊<mst[6],6>=4加入MST

此時,因為點V6的加入,需要更新lowcost數組和mst數組,為什么要這么更新?因為當從v3里面選出v6的時候,這個時候我們就從v6開始繼續規划,因為v6的對應權值數組是

v6:{*,*,4,2,6,0}

而此時lowcost數組值是:{1,5,0,5,6,0}

這時我們拿lowcost數組和v6對應的權值數組比較(下標要對應),把v6里比low里小的值替換給low數組(這么做的意義是,例如,下標為3時,v6是2,low是5,也就是說,下標為3對應的頂點是v4,v4可以選擇和v6連接(因為權值2<5),所以5會替換2),這樣得到的最終lowcost為: 

lowcost[2]=5,lowcost[3]=0,lowcost[4]=2,lowcost[5]=6,lowcost[6]=0

mst[2]=3,mst[3]=0,mst[4]=6,mst[5]=3,mst[6]=0

明顯看出,以V4為終點的邊的權值最小=2,所以邊<mst[4],4>=4加入MST

此時,因為點V4的加入,需要更新lowcost數組和mst數組,為什么要這么更新?因為當從v6里面選出v4的時候,這個時候我們就從v4開始繼續規划,因為v4的對應權值數組是

 

v4:{5,*,5,0,*,2}

 

而此時lowcost數組值是:{1,5,0,0,6,0}

 

這時我們拿lowcost數組和v4對應的權值數組比較(下標要對應),把v4里比low里小的值替換給low數組,但是可惜的是,沒有找到v4里要比lowcost小的(0不算這樣得到的最終lowcost為: 

 

lowcost[2]=5,lowcost[3]=0,lowcost[4]=0,lowcost[5]=6,lowcost[6]=0

mst[2]=3,mst[3]=0,mst[4]=0,mst[5]=3,mst[6]=0

明顯看出,以V2為終點的邊的權值最小=5,所以邊<mst[2],2>=5加入MST

此時,因為點V2的加入,需要更新lowcost數組和mst數組,為什么要這么更新?因為當從v4里面選出v2的時候,這個時候我們就從v2開始繼續規划,因為v2的對應權值數組是

v2:{6,0,5,*,3,*}

而此時lowcost數組值是:{1,0,0,0,6,0}

這時我們拿lowcost數組和v2對應的權值數組比較(下標要對應),把v2里比low里小的值替換給low數組,找到v2里要比lowcost小的(0不算這樣得到的最終lowcost為: 

lowcost[2]=0,lowcost[3]=0,lowcost[4]=0,lowcost[5]=3,lowcost[6]=0

mst[2]=0,mst[3]=0,mst[4]=0,mst[5]=2,mst[6]=0

很明顯,以V5為終點的邊的權值最小=3,所以邊<mst[5],5>=3加入MST

lowcost[2]=0,lowcost[3]=0,lowcost[4]=0,lowcost[5]=0,lowcost[6]=0

mst[2]=0,mst[3]=0,mst[4]=0,mst[5]=0,mst[6]=0

至此,MST構建成功,如圖所示:

 

代碼如下(僅供參考!):

 

import java.util.LinkedList;

public class MyTestGraph {
	private int vertexSize;// 頂點數
	private int[] vertexs;// 頂點的一維數組
	private int[][] matrix;// 鄰接矩陣
	private static final int MAX_WEIGHT = 1000;
	private boolean[] isVisited;

	public MyTestGraph(int vertexSize) {
		this.vertexSize = vertexSize;
		this.matrix = new int[vertexSize][vertexSize];
		vertexs = new int[vertexSize];
		for (int i = 0; i < vertexSize; i++) {
			vertexs[i] = i;
		}
		isVisited = new boolean[vertexSize];
	}

	public int[][] getMatrix() {
		return matrix;
	}

	public void setMatrix(int[][] matrix) {
		this.matrix = matrix;
	}

	public void prim() {
		int[] lowcost = new int[vertexSize];
		int[] adjvex = new int[vertexSize];
		int min, minId, sum = 0;
		for (int i = 1; i < vertexSize; i++) {
			lowcost[i] = matrix[0][i];
		}
		for (int i = 1; i < vertexSize; i++) {
			min = MAX_WEIGHT;
			minId = 0;
			for (int j = 1; j < vertexSize; j++) {
				if (lowcost[j] < min && lowcost[j] > 0) {
					min = lowcost[j];
					minId = j;
				}
			}
			System.out.println("頂點:" + adjvex[minId] + "權值:" + min);
			sum += min;
			lowcost[minId] = 0;
			for (int j = 1; j < vertexSize; j++) {
				if (lowcost[j] != 0 && matrix[minId][j] < lowcost[j]) {
					lowcost[j] = matrix[minId][j];
					adjvex[j] = minId;
				}
			}
		}
		System.out.println("最小生成樹權值總和為:" + sum);
	}

	public static void main(String[] args) {
		MyTestGraph graph = new MyTestGraph(9);
		int[] a1 = new int[] { 0, 10, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 11,
				MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT };
		int[] a2 = new int[] { 10, 0, 18, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT,
				16, MAX_WEIGHT, 12 };
		int[] a3 = new int[] { MAX_WEIGHT, MAX_WEIGHT, 0, 22, MAX_WEIGHT,
				MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 8 };
		int[] a4 = new int[] { MAX_WEIGHT, MAX_WEIGHT, 22, 0, 20, MAX_WEIGHT,
				MAX_WEIGHT, 16, 21 };
		int[] a5 = new int[] { MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 20, 0, 26,
				MAX_WEIGHT, 7, MAX_WEIGHT };
		int[] a6 = new int[] { 11, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 26, 0,
				17, MAX_WEIGHT, MAX_WEIGHT };
		int[] a7 = new int[] { MAX_WEIGHT, 16, MAX_WEIGHT, MAX_WEIGHT,
				MAX_WEIGHT, 17, 0, 19, MAX_WEIGHT };
		int[] a8 = new int[] { MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 16, 7,
				MAX_WEIGHT, 19, 0, MAX_WEIGHT };
		int[] a9 = new int[] { MAX_WEIGHT, 12, 8, 21, MAX_WEIGHT, MAX_WEIGHT,
				MAX_WEIGHT, MAX_WEIGHT, 0 };
		graph.matrix[0] = a1;
		graph.matrix[1] = a2;
		graph.matrix[2] = a3;
		graph.matrix[3] = a4;
		graph.matrix[4] = a5;
		graph.matrix[5] = a6;
		graph.matrix[6] = a7;
		graph.matrix[7] = a8;
		graph.matrix[8] = a9;
	}
}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM