JAVA实践Dijkstra算法求最短路径距离
来源:互联网 发布:js数组赋值 编辑:程序博客网 时间:2024/06/10 19:25
前言
Dijkstra算法用于求指定顶点到其他顶点的最短距离,时间复杂度O(N^2),据说可以使用堆优化到O(log N),然而还不会。
其特点是(对我来说)非常容易求得路径,和对应的距离。
缺陷也是存在的,此算法不能处理负权边。即距离为负时,就挂了。
此文内容同样参考《啊哈,算法》
另外个人感觉代码可能有错,还望有心人指点。
功能实现
输入一个顶点
输出路径
输出与路径对应的距离
如果存在不可到达的顶点,则输出该顶点不可到达
中文版参考
对应的二维数组
{0, 1, 12, INF, INF, INF}, {INF, 0, 9, 3, INF, INF}, {INF, INF, 0, INF, 5, INF}, {INF, INF, 4, 0, 13, 15}, {INF, INF, INF, INF, 0, 4}, {INF, INF, INF, INF, INF, 0}
/** * Dijkstra算法 * * 指定一个顶点,求该顶点到各个顶点的最短路径 * Step 1: * 选择一个顶点,如顶点1 * 使用布尔数组记录mark[1] = true; * 表示已经最短 * Step 2: * 遍历各个顶点到达顶点1的长度,不能到达的为无穷大,到自己本身的为0 * 使用与顶点个数大小相同的一维数组dis存储所有距离,此时为估计距离 * 估计距离dis数组存储的是[顶点1],到达其他顶点的距离 * 记录距离顶点1最近(距离最短)的顶点,即dis中最小的数,但是不能为0 * 此处2号顶点距离顶点1最近,所以选择到达顶点2,此时顶点2已确定距离顶点1最短 * dis: [0 1 12 inf inf inf] * Step 3: * 选择进入顶点2 * 表示顶点2已经最短,使用布尔数组记录mark[2] = true; * 遍历各个顶点到达顶点2的长度,将其与dis中的估计距离比较,小于估计距离的更新之 * 遍历后得出 * * 顶点2到顶点4的距离是3 * 顶点2到顶点3的距离是9 * * 顶点1到顶点2的距离为1 * 顶点2到顶点3的距离为9 * 相加起来就是顶点1到顶点4的最短距离:10 * 比原来的小,更新估计顶点3的距离 * dis: [0 1 10 inf inf inf] * * 顶点2到顶点4的距离为3 * 顶点1到顶点2的距离为1 * 相加起来就是顶点1到顶点4的最短距离:4 * 比原来小,更新顶点4的估计距离 * dis: [0 1 10 4 inf inf] * * 找出距离顶点1最近的,又未确定最短的顶点 * 即mark[n] = false,同时数值最小的。 * 这里mark[1]、mark[2]都是true,排除之后,数值最小的是4,选择它 * Step 4: * 选择进入顶点4 * 表示顶点4已经最短,使用布尔数组记录mark[4] = true; * 遍历各个顶点到达顶点4的长度,将其与dis中的估计距离比较,小于估计距离的更新之 * 遍历后得出 * * 顶点4到顶点3的距离是4 * 顶点4到顶点5的距离是13 * 顶点4到顶点6的距离是15 * * 顶点1到顶点4的距离是4 * 将距离相加,得到 * dis: [0 1 8 4 17 19] * 排除顶点1、2、4找最近的顶点,就是顶点3 * Step n: * 重复选择距离最近的顶点 * 进入,并标记已最短 * 寻找新的距离,并更新估计距离 * 排除已确定顶点,再次寻找最小数值顶点 */
代码实现
public class DijkstraDemo { static int INF = 99; static int[][] arr = new int[][] { {0, 1, 12, INF, INF, INF}, {INF, 0, 9, 3, INF, INF}, {INF, INF, 0, INF, 5, INF}, {INF, INF, 4, 0, 13, 15}, {INF, INF, INF, INF, 0, 4}, {INF, INF, INF, INF, INF, 0} }; public static void main(String[] args) { int point = 1; System.out.println("起点为" + point); dijkstra(point); System.out.println(); point = 2; System.out.println("起点为" + point); dijkstra(point); } public static void dijkstra(int point) { //顶点-1对应角标位置 point--; //顶点个数 int n = arr.length; //用于标记已经确定为最短距离的顶点 boolean[] mark = new boolean[n]; //存储最短距离时其在数组中的位置 int nextMin = point; //用于记录找到的最短距离 int nextMinDis; //当前进入的顶点在数组中的位置 int curMin = point; //如果该不可到达,不应该记录 boolean flag = true; //存储估计距离 int[] dis = new int[n]; //初始化估计距离 initArray(dis, point); //记录遍历次数 int count = 0; //记录路径 int[] path = new int[n]; int tail = 0; while (true) { //当前被选择的顶点,标记为真 mark[curMin] = true; nextMinDis = INF; //每选择一次,自增 count++; //如果flag为假,则存在不可到达的顶点,不必将其存储为路径之一 if (flag) { path[tail++] = curMin + 1; flag = false; } //选择的顶点个数已经是所有顶点,可以写成for循坏的,i<n即可 if (count == n) { break; } //System.out.println("--------------------------------------"); for (int i = 0; i < n; i++) { //比较顶点i的估计距离 与前一个最短距离顶点到顶点i的距离 //取较小者 if (dis[i] > dis[curMin] + arr[curMin][i]) { dis[i] = dis[curMin] + arr[curMin][i]; flag = true; System.out.println("顶点" + (curMin+1) + "到达顶点" + (i+1) + ",距离" + dis[i]); } //获取更新后距离顶点1最短且尚未确定的顶点 if (!mark[i] && dis[i] < nextMinDis) { nextMinDis = dis[i]; nextMin = i; flag = true; } } //System.out.println("--------------------------------------"); curMin = nextMin; } System.out.println("最短路径与距离:"); for (int i = 0; i < tail; i++) { System.out.print(path[i]); if (i != tail - 1) { System.out.print("→"); } } System.out.println(); for (int i = 0; i < tail; i++) { System.out.print(dis[path[i] - 1]); if (i != tail - 1) { System.out.print("--"); } } System.out.println(); for (int i = 0; i < n; i++) { if (!mark[i]) { System.out.println("顶点" + (i+1) + "不可到达"); } } } public static void initArray(int[] dis, int point) { // 初始化估计距离,指定起点距离为0 // 其他未确定的都是,距离该顶点的距离 dis[point] = 0; for (int i = 0; i < dis.length; i++) { if (i != point) { dis[i] = arr[point][i]; //System.out.println(dis[i] + " i=" + i); } } }}
结果
起点为1顶点2到达顶点3,距离10顶点2到达顶点4,距离4顶点4到达顶点3,距离8顶点4到达顶点5,距离17顶点4到达顶点6,距离19顶点3到达顶点5,距离13顶点5到达顶点6,距离17最短路径与距离:1→2→4→3→5→60--1--4--8--13--17起点为2顶点4到达顶点3,距离7顶点4到达顶点5,距离16顶点4到达顶点6,距离18顶点3到达顶点5,距离12顶点5到达顶点6,距离16最短路径与距离:2→4→3→5→60--3--7--12--16顶点1不可到达
结束语
寻找最短路径的应用还是不少的,做这个给我一种在做地图导航的感觉。成就Max。。。
每次写出中文思路,可以找出思维漏洞,写代码卡壳了就回去看思路,再写,很不错的一种方式。
当然这种思路只有自己能看懂了(逃
END
0 0
- JAVA实践Dijkstra算法求最短路径距离
- Dijkstra算法求最短路径(java)
- Dijkstra算法求最短路径(java)
- JAVA实践Bellman-Ford最短路径距离算法
- dijkstra 求最短路径算法
- Dijkstra算法求最短路径
- Dijkstra 算法求最短路径
- Dijkstra算法求最短路径
- Dijkstra算法求最短路径
- Dijkstra 求最短路径算法
- Dijkstra算法 ---求最短路径
- Dijkstra算法求最短路径
- dijkstra算法求最短路径
- dijkstra算法求最短路径
- Dijkstra算法求最短路径
- dijkstra算法求最短路径
- 【算法】Dijkstra 求最短路径算法
- Java迪杰斯特拉算法(Dijkstra算法)求最短路径
- bootstrap table单元格样式,行样式以及分页显示全部的设置
- memcpy用法
- 2016最新界面设计(APP和HTML)
- redis数据类型List的安全队列和不安全队列
- 图解正向代理、反向代理、透明代理
- JAVA实践Dijkstra算法求最短路径距离
- ABAP触发BW处理链的两种方法
- CSS布局分享
- PHP中参数校验和取值
- Eigen 快速学习
- chgrp/chmod/chown/ln 命令详解
- 最流行强大的页面标签框架 display:table 使用
- common.constant 常量枚举类型
- 【Android】解决Genymotion无法打开