浅谈最小生成树的算法思路(一)Prim算法
来源:互联网 发布:淘宝网围巾专卖 编辑:程序博客网 时间:2024/05/01 04:40
Prim算法是求最小生成树的一种常见算法,简单谈一下笔者自己的理解。
算法思路
- 设已经确定的点集为P,初始为空。设还未确定的点集为Q,初始为该图所有点的集合。设已经确定的边为X,初始为空。
- 选取任意一点作为起始点,将该点添加到集合P中,并从Q中移除该点。
- 从P中找到一个点A,从Q中找到一个点B,使得2点之间的路径AB的权值最小。
- 将路径AB添加到X,将Q中的点B添加到集合P中,并从Q中移除该点。
- 重复3~4,直至所有点确定路径。
代码思路
- 采用邻接矩阵保存图。
- 创建一个临时数组lowcost,长度为总点数,用于表示当前时刻集合P与各点的距离。
例如lowcost[3]=m,3表示下标为3的点,当m为0表示该点已经在集合P中,即已经确定;当m为65535,表示该点与集合P暂时没有直接路径可到达;其他值表示该点与P可以直接通过一条连线到达,并且当前最短距离为m。
需要说明的是,这个数组是会不断变化的,最初,当P中只有一个点A的时候,lowcost表示A到各点的距离,这个时候有些点与点A没有直达路径,此时这些点是为65535的;而程序结束时,该数组的元素的值将都为0,因为所有点已经都添加到P了,此时各点到P的距离都为0。 - 创建临时数组mst,长度为总点数,用于保存步骤2的最短距离m对应的边关系。即每次添加一个点到P后,会更新P与剩余各点之间的最短距离m,此时会记录最短距离的边AB的起始点和结束点。
例如lowcost[3]=m,mst[3]=2表示下标为3的点A到P的距离为m,该连线是A与P中下标为2的点B的连线。 - 初始化:选取图的点集合的下标为0的点A,作为初始点。将图的边矩阵中,A与各点的距离(权重)写入lostcost数组作为初始值,并将mst各元素置零。创建临时变量n=1,表示已经确定的点数,用作循环结束的判断。
- 遍历lowcost数组,找出最小的值(排除0和65535),即当前集合P中任意一点到Q中任意一点的最短距离(权重)。记录下标minid。
- 将lowcost[minid]置为零,表示该点已经添加到P。
- 更新新添加到P的点minid与Q中各点的距离。即遍历图的边矩阵中起始点为minid的各元素,如果有比lowcost中对应元素的距离小的元素,则更新lostcost,同时更新mst。
例如,此时P中有3个点{A,B,C},Q中有2个点{D,E},C为刚刚添加的点。由于我们刚刚将C添加到P,所以执行步骤7之前的lostcost数组中保存着{A,B}到{C,D,E}的最短距离,比如lostcost为[0,0,0,Sd,Se]。当C添加进去之后,有可能之前AB到DE都距离比较远或者没有直接路径,而C到DE的距离很近,这个时候就需要比较C到DE的距离Scd和Sce有没有比Sd,Se更小,如果有则更新lostcost中的Sd,Se为一个新的值。 - 循环执行5~7,直至所有点的路径确定,即当n>=总点数跳出循环。
代码实现(Java版)
public class Prim { static int MAX = 65535;//表示两点之间没有直接路径 public static void prim(int[][] graph, int n) { char[] c = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'E', 'F'}; int[] lowcost = new int[n]; int[] mst = new int[n]; int i, j, min, minid, sum = 0; //初始化数组,即将点A添加到P中,计算与各点的距离 for (i = 1; i < n; i++) { lowcost[i] = graph[0][i]; mst[i] = 0; } //i为已经确定的点数,由于点A已经确定,故初始化为1 for (i = 1; i < n; i++) { min = MAX; minid = 0; //找到P到Q的最短路径,将点添加到P for (j = 1; j < n; j++) { if (lowcost[j] < min && lowcost[j] != 0) { min = lowcost[j]; minid = j; } } System.out.println(c[mst[minid]] + "到" + c[minid] + " 权值:" + min); sum += min; lowcost[minid] = 0; //如果新添加到P的点minid带来了与Q中剩余点的更短路径,更新lowcost、mst数组 for (j = 1; j < n; j++) { if (graph[minid][j] < lowcost[j]) { lowcost[j] = graph[minid][j]; mst[j] = minid; } } } System.out.println("sum:" + sum); } public static void main(String[] args) { int[][] map = new int[][]{ {0, 10, MAX, MAX, MAX, 11, MAX, MAX, MAX}, {10, 0, 18, MAX, MAX, MAX, 16, MAX, 12}, {MAX, MAX, 0, 22, MAX, MAX, MAX, MAX, 8}, {MAX, MAX, 22, 0, 20, MAX, MAX, 16, 21}, {MAX, MAX, MAX, 20, 0, 26, MAX, 7, MAX}, {11, MAX, MAX, MAX, 26, 0, 17, MAX, MAX}, {MAX, 16, MAX, MAX, MAX, 17, 0, 19, MAX}, {MAX, MAX, MAX, 16, 7, MAX, 19, 0, MAX}, {MAX, 12, 8, 21, MAX, MAX, MAX, MAX, 0} }; prim(map, map.length); }}
1 0
- 浅谈最小生成树的算法思路(一)Prim算法
- 最小生成树(一)-----Prim算法
- Prim 算法生成的最小生成树
- 浅谈最小生成树的算法思路(二)Kruskal算法
- 无向带权图的最小生成树算法——Prim及Kruskal算法思路
- 无向带权图的最小生成树算法——Prim及Kruskal算法思路
- 最小生成树prim算法实现及1233解题思路
- hiho最小生成树一(prim)算法
- 最小生成树算法(一)--对prim算法的理解
- 最小生成树的prim算法代码
- 最小生成树的prim算法实现
- 构造最小生成树的 prim 算法
- 最小生成树的Prim算法
- 图的最小生成树(prim算法)
- 最小生成树的prim算法
- 最小生成树的prim算法
- JAVA的最小生成树(prim)算法
- 最小生成树的prim算法实现
- servlet 基础之1
- C语言字节对齐(以32位系统为例)
- C语言笔试经典--求分数数列的和
- Android:储存方式之SharePreferences
- 在没有安装终端服务的Windows 2012 R2服务器上配置远程桌面的属性
- 浅谈最小生成树的算法思路(一)Prim算法
- Maven学习 (一) 搭建Maven环境
- hdoj4907Task schedule【二分】
- Linux常用命令之三
- Smarty模版引擎
- Gallery和GridView浅析
- 深入理解堆和栈的区别
- 如何拦截Activity的启动(二)
- linux内核模块和驱动程序的编写