Dijkstra算法的Java实现
2013-12-09 17:39
309 查看
迪科斯彻(Dijkstra)算法使用了广度优先搜索解决非负权有向图的单源最短路径问题,算法最终得到一个最短路径树。
在一个有向非负权重的图中,可以知道如AC>AB,这AC+CB>AB,这一不等式有点贪心算法的思想,每次选择时都做出贪心选择。在迪科斯彻算法中就是使用了上面的原理进行求解的。具体的介绍可以wiki一下:http://zh.wikipedia.org/wiki/Dijkstra算法.里面已经包含了伪代码。下面是Java版的实现代码,需要注意的是这里没有使用伪代码中的优先队列,而是使用一个布尔类型的标记数组来通过标记来模拟优先队列的"出队列"。
运行效果:
对应的图结构:
![](http://img.blog.csdn.net/20131209173650765?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTYzODg4Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
O啦~~~
装载请保留出处:/article/2121239.html
谢谢!!
在一个有向非负权重的图中,可以知道如AC>AB,这AC+CB>AB,这一不等式有点贪心算法的思想,每次选择时都做出贪心选择。在迪科斯彻算法中就是使用了上面的原理进行求解的。具体的介绍可以wiki一下:http://zh.wikipedia.org/wiki/Dijkstra算法.里面已经包含了伪代码。下面是Java版的实现代码,需要注意的是这里没有使用伪代码中的优先队列,而是使用一个布尔类型的标记数组来通过标记来模拟优先队列的"出队列"。
package com.wly.algorithmbase.search; /** * 迪科斯彻算法 * 基于广度优先搜索,使用优先队列存储检索信息 * 伪代码: 1 function Dijkstra(G, w, s) 2 for each vertex v in V[G] // 初始化 3 d[v] := infinity // 將各點的已知最短距離先設成無窮大 4 previous[v] := undefined // 各点的已知最短路径上的前趋都未知 // 因为出发点到出发点间不需移动任何距离,所以可以直接将s到s的最小距离设为0 5 d[s] := 0 6 S := empty set 7 Q := set of all vertices 8 while Q is not an empty set // Dijkstra演算法主體 9 u := Extract_Min(Q) 10 S.append(u) 11 for each edge outgoing from u as (u,v) 12 if d[v] > d[u] + w(u,v) // 拓展边(u,v)。w(u,v)为从u到v的路径长度。 13 d[v] := d[u] + w(u,v)// 更新路径长度到更小的那个和值。 14 previous[v] := u // 紀錄前趨頂點 * @author wly * */ public class DijstraAlgorithm { private static int IMAX = 10000; //不连通状态 public static int[][] adjMat = { {0,10,3,IMAX}, {IMAX,0,4,5}, {IMAX,4,0,10}, {IMAX,IMAX,IMAX,0} }; public static void main(String[] args) { DijstraAlgorithm dijstraAlgorithm = new DijstraAlgorithm(); int start = 2; int end = 3; System.out.println("------测试------"); System.out.println("\n从" + start + "到" + end + "的距离是:" + dijstraAlgorithm.reslove(adjMat, start, end)); System.out.println("------测试------"); start = 0; end = 3; System.out.println("\n从" + start + "到" + end + "的距离是:" + dijstraAlgorithm.reslove(adjMat, start, end)); } /** * 在用邻接矩阵adjMat表示的图中,求解从点s到点t的最短路径 * @param adjMat 邻接矩阵 * @param s 起点 * @param t 终点 * @return */ public int reslove(int[][] adjMat,int s,int t) { //判断参数是否正确 if(s < 0 || t < 0 || s >=adjMat.length || t >= adjMat.length) { System.out.println("错误,顶点不在图中!"); return IMAX; } //用来记录某个顶点是否已经完成遍历,即替代优先队列的"移出队列"动作 boolean[] isVisited = new boolean[adjMat.length]; //用于存储从s到各个点之间的最短路径长度 int[] d = new int[adjMat.length]; //初始化数据 for(int i=0;i<adjMat.length;i++) { isVisited[i] = false; d[i] = IMAX; } d[s] = 0; //s到s的距离是0 isVisited[s] = true; //将s标记为已访问过的 //尚未遍历的顶点数目,替代优先队列是否为空的判断即Queue.isEmpty() int unVisitedNum = adjMat.length; //用于表示当前所保存的子路径中权重最小的顶点的索引,对应优先队列中,默认是起点 int index = s; while(unVisitedNum > 0 && index != t) { int min = IMAX; for(int i=0;i<adjMat.length;i++) { //取到第i行的最小元素的索引 if(min > d[i] && !isVisited[i]) { min = d[i]; index = i; } } if(index == t || unVisitedNum == 0) { System.out.print(index); //打印最短路径 } else { System.out.print(index + "=>"); //打印最短路径 } for(int i=0;i<adjMat.length;i++) { if(d[index] + adjMat[index][i] < d[i]) { d[i] = d[index] + adjMat[index][i]; } } unVisitedNum --; isVisited[index] = true; } return d[t]; } }
运行效果:
------测试------ 2=>1=>3 从2到3的距离是:9 ------测试------ 0=>2=>1=>3 从0到3的距离是:12
对应的图结构:
O啦~~~
装载请保留出处:/article/2121239.html
谢谢!!
相关文章推荐
- SpringMVC深度探险(三) —— DispatcherServlet与初始化主线 博客分类:
- Eclipse小缺陷及规避方法积累
- Spring的声明式事务管理<tx:advice/> 有关的设置
- Java aes加密C#解密的取巧方法
- java农历/旧历的计算代码
- java输入输出流
- Java获取获取汉字拼音和首字母代码
- Java泛型的详解
- struts-2.3.1+spring-framework-3.2.2+hibernate-4.1.1整合历程<第一部分>(详解)
- Struts2的注解功能
- java 对象序列化xml方法
- Struts2的exception配置
- 基于struts2的web系统中的返回功能
- java 性能杂谈
- Java有趣的三元运算符
- java io的选择
- Java Socket实战之七 使用Socket通信传输文件
- java 将GBK编码文件转为UTF-8编码
- Java中的对象析构与finalize方法
- SSH框架系列:Spring配置多个数据源