这一算法的核心其实就是Dijkstra算法,这也是上一篇文章写Dijkstra的原因。但是有一点不同:Dijkstra是单源最短路径,即每个点到原点的最短路径。
Prim算法的核心是每一个点到最小生成树的最短路径。下面上代码
Java版:
import java.util.Arrays; public class PrimBasic { //初始化最大值 static double max = Double.POSITIVE_INFINITY; //初始化一个邻接矩阵 static double[][] map= new double[][]{ {0, 1, 2, max, max, max}, {1, 0, 6, 11, max, max}, {2, 6, 0, 9, 13, max}, {max, 11, 9, 0, 7, 3}, {max, max, 13, 7, 0, 4}, {max, max, max, 3, 4, 0} }; static int n = map.length; //初始化距离矩阵,记录点到 生成树 的最短距离 static double[] dis = map[0]; //初始化一个标记数组,记录哪些点被确定 static int[] book = new int[n]; static void primBasic(int startPoint) { //将起始点在book数组中标记 book[startPoint] = 1; //初始化一个计数变量 int count = 1; //初始化一个变量,存储最小生成树中所有边的权值之和 while (count != n) { //初始化一个最小值变量,存储点到 生成树 的最小权值 double min = 999; //初始化一个变量,存储dis距离数组中最小值的下标 int u = -1; //找到dis距离数组中权值最小的点,将这点确定下来 for (int i = 0; i < n; i++) { if (dis[i] < min && book[i] == 0) { min = dis[i]; u = i; } } book[u] = 1; count ++; //更新这一确定点的出边能到达的点 在dis中的权值 for (int j = 0; j < n; j++) { if (dis[j] > map[u][j] && book[j] == 0) { dis[j] = map[u][j]; } } } return; } public static void main(String[] args) { primBasic(0); System.out.println(Arrays.toString(dis)); int sum = 0; for (int i = 0; i < dis.length; i++) { sum += dis[i]; } System.out.println(sum); } }
python版:
import numpy as np #声明一个邻接矩阵,表示各个点及点之间的权值 global e #声明一个距离列表,存储各个点到生成树的距离 global dis #声明一个book列表,用来标记哪些点在生成树中 global book def prim(startpoint): # 初始化一个计数变量count,存储生成树中节点的个数,当所有节点都存入生成树中之后,退出方法 count = 0 #将起始点放入生成树中,作为生成树的根节点 book[startpoint] = 1 n = len(e) while count != n: #定义一个变量存储每个点在dis列表中的权值,从而帮助找到生成树之外的点中权值最小的点 #这一点一定要在while循环内部定义,才能保证每趟循环能顺利找出最小值点 min = 999 #定义一个变量存储生成树外权值最小的点的下标,同样也要在while循环内部定义 u = -1 for i in range(n): if dis[i] < min and book[i] == 0: #循环比较,找出生成树外权值最小的点 min = dis[i] u = i #将这一点加入到生成树中,并在book列表中标记 count += 1 book[u] = 1 #循环遍历生成树外的点,找到距离新加入生成树的点最近的点,也就是距离生成树最近的点 for j in range(n): if dis[j] > e[u][j] and book[j] == 0: dis[j] = e[u][j] #上面这步循环遍历就把dis列表中所有点的权值更新了,while的下一轮循环将会从dis列表中生成树之外的点中 #找到权值最小的点加入到生成树中 #while循环结束后,生成树中已经包含了所有的节点,退出方法 return if __name__ == '__main__': max = float('inf') e = [ [0, 1, 2, max, max, max], [1, 0, 6, 11, max, max], [2, 6, 0, 9, 13, max], [max, 11, 9, 0, 7, 3], [max, max, 13, 7, 0, 4], [max, max, max, 3, 4, 0] ] dis = e[0] book = np.zeros((len(e),), dtype='int') prim(0) print(dis) sum = 0 for num in dis: sum += num print(sum)
正确输出为19
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)