JAVA的最小生成树(prim)算法

好久没更新博客了,由于离散数学的实践项目和SDN学习的需要,这次要学习一下图的最小生成树(PRIM)算法,前后花了大半天去了解算法和编写算法,刚开始的时候写没有借鉴github,现在动头脑自己写的机会太少了,所有的算法百度一下都有源码,实在是需要锻炼一下自己,不过写出来的代码的确效率不高,不过没关系,慢慢进步吧。


PRIM算法的简介我这里就不COPY百度了,PRIM算法是基于点的图算法,对应的还有基于边的kruskal算法,我还没学习,等学习了后会将其以及深搜和广搜一并加进去的。

 

其中的算法步骤如下:

(1)先取一个点,一般为V1,然后得到V1所在行的数组存进lowcost[]里,

(2)然后得到lowcost数组里面最小的值,即为下一个跳转的点,将点传进结果数组。

(3)将下一个点所在的矩阵和lowcost[]进行垂直对比,把小于原来数组对应的值赋给lowcost[]进行转换。

(4)再得到lowcost中最小值,将跳转的点传进结果数组。

(5)重复上述步骤直到结束。


代码如下:

import java.util.ArrayList;
import java.util.List;

public class Prim {

	private static final int MAX = 10000;
	private static final List Point = new ArrayList();
	private static final List results = new ArrayList();
	private static final int[][] array = new int[5][5];
	private static int[] weights = new int[5];

	public static void main(String[] args) {

		Add(array);// 邻接矩阵初始化
		prim(array);
		Print();

	}
	public static void Add(int[][] a) {
		// 数组所有元素先赋值MAX
		for (int i = 0; i < array.length; i++) {
			for (int j = 0; j < array.length; j++) {
				array[i][j] = MAX;
			}
		}
		// 这里只是添加点的名字V1-V5
		for (int i = 0; i < array.length; i++) {
			int j = i + 1;
			Point.add("V" + j);
		}
		// 赋值
		a[0][1] = 3;
		a[0][3] = 2;
		a[0][4] = 1;
		a[1][0] = 3;
		a[1][2] = 4;
		a[1][4] = 5;
		a[2][1] = 4;
		a[2][3] = 2;
		a[2][4] = 6;
		a[3][0] = 2;
		a[3][2] = 2;
		a[3][4] = 4;
		a[4][0] = 1;
		a[4][1] = 5;
		a[4][2] = 6;
		a[4][3] = 4;
		/*
		 * v1 v2 v3 v4 v5 
		 * {MAX,3,MAX,2,1},
		 * {3,MAX,4,MAX,5}, 
		 * {MAX,4,MAX,2,6},
		 * {2,MAX,2,MAX,4}, 
		 * {1,5,6,4,MAX}
		 */
	}

	public static void prim(int[][] array) {
		int[] lowcost = new int[5];// 最小代价的数组,会发生变化
		int start = 0;// 这是每次得到最小值在lowcost数组中的下标
		int count = 0;// 循环次数

		for (int i = 0; i < 5; i++) {
			lowcost[i] = array[0][i];
		}

		results.add(Point.get(start));
		lowcost[start] = 0;

		while (count < array.length - 1) {
			int min = MAX;
			for (int i = 0; i < lowcost.length; i++) {

				if (lowcost[i] != 0 && lowcost[i] < min) {
					min = lowcost[i];
				}

			}

			weights[count] = min;
			start = GetIndex(lowcost, min);
			results.add(Point.get(start));
			lowcost[start] = 0;
			// 垂直对比,改变lowcost数组
			for (int i = 0; i < lowcost.length; i++) {
				if (lowcost[i] > array[start][i]) {
					lowcost[i] = array[start][i];
				}
			}
			count++;
		}

	}

	public static int GetIndex(int[] a, int n) {

		for (int i = 0; i < a.length; i++) {
			if (a[i] == n)
				return i;
		}
		return -1;
	}

	// 得到最近的点
	public static String GetClose(int[][] a, int i) {
		int close = a[i][0];
		int index = 0;
		for (int j = 1; j < 5; j++) {

			if (a[i][j] < close) {
				close = a[i][j];
				index = j;
			}
		}
		String close_name = Point.get(index);// 得到原来去的点
		return close_name;
	}

	public static void Print() {
		for (int i = 0; i < 5; i++) {
			if (i == 0) {
				System.out.println("初始位置:" + results.get(i));
			} else {
				int index = Point.indexOf(results.get(i));
				String close = GetClose(array, index);
				System.out.println("加入点:" + results.get(i) + "路线:" + close
						+ "-->" + results.get(i) + ":--权值:" + weights[i]);
			}
		}
	}

}

结果:

初始位置:V1

加入点:V5路线:V1-->V5:--权值:2
加入点:V4路线:V1-->V4:--权值:2
加入点:V3路线:V4-->V3:--权值:3
加入点:V2路线:V1-->V2:--权值:0


你可能感兴趣的:(Java,算法,最小生成树,PRIM)