2019独角兽企业重金招聘Python工程师标准>>>

package org.loda.graph;import org.loda.structure.Stack;
import org.loda.util.In;/*** * @ClassName: Johnson 时间复杂度:EVlgV* @Description: 稀疏图上的johnson算法,由于稀疏图的数据结构推荐使用邻接链表,所以这里也采用邻接链表,该算法也是给稀疏图使用的,如果是密集图,推荐使用实现较为简单的FloydWashall算法,可以保证V^3的时间复杂度* * Johnson算法使用的方式相当于给每个边都加了一个权重,使得所有边都为非负数,这样就能对每个边使用较为高效的Dijkstra算法。* 注意的是不能简单的给每个边加相同的值然后使得所有边都变成非负数,原因为假设从a->b有两条路径,一条权重为1+1,一条为2,本应权重和相等;如果都加1,则变成了2+2和3,不一致了,就会导致更新了不该更新的边* * Johnson比较巧妙的引入了h函数来解决这个问题,通过这个函数进行每个边的重新赋值权重* * @author minjun* @date 2015年6月2日 下午5:49:13* */
public class Johnson {/*** 权重函数h 用来重新赋予权重的函数,利用数组存储每个i对应的权重函数值*/private double[] h;/*** 距离*/private double[][] dist;/*** 前驱节点*/private int[][] prev;/*** 是否含有负环*/private boolean negativeCycle;@SuppressWarnings("unchecked")public Johnson(WeightDigraph g) {int v = g.v();h = new double[v];dist = new double[v][v];prev = new int[v][v];// 先进行一次BellmanFord算法,用来判断是否存在负环,如果存在则停止计算最短路径BellmanFord bf = new BellmanFord(g, 0);if (bf.hasNegCycle()) {negativeCycle = true;System.out.println("有负环,不存在最短路径...");return;}/*** 利用Johnson算法计算最短路径*/computeShortestPath(g);}public void computeShortestPath(WeightDigraph g) {int v = g.v();// 创建一个新的图G,G含有一个多余的顶点s'作为原点计算h函数(目前将s'设为索引为v的顶点)WeightDigraph G = new WeightDigraph(v + 1);for (int i = 0; i < v; i++) {// 将新的顶点v和其他节点相连,并将他们的距离设为0G.add(v, i, 0);for (Edge e : g.adj(i)) {int j = e.otherSide(i);G.add(i, j, e.weight());}}int V = G.v();BellmanFord bf = new BellmanFord(G, V - 1);// 为权重函数赋值for (int i = 0; i < v; i++) {h[i] = bf.distTo(i);}WeightDigraph wg = new WeightDigraph(v);//创建一个新的图,将所有更新权重后的节点和边加到该图中,这时的图为非负权重图,可以对他使用Dijkstra算法for (int i = 0; i < v; i++) {for (Edge e : g.adj(i)) {int j = e.otherSide(i);wg.add(i, j, e.weight() + h[i] - h[j]);}}for (int i = 0; i < v; i++) {//对每个节点使用Dijkstra算法Dijkstra d = new Dijkstra(wg, i);for (int j = 0; j < v; j++) {//由于每个边都加了一定的权重,这里为了还原到原始距离,就将增加的权重减去dist[i][j] = d.distTo(j) + h[j] - h[i];d.pathTo(i);prev[i]=d.prev;}}}/*** * @Title: hasNegtiveCycle* @Description: 是否含有负环* @param @return 设定文件* @return boolean 返回类型* @throws*/public boolean hasNegtiveCycle() {return negativeCycle;}/*** * @Title: distTo* @Description: i->j的距离* @param @param i* @param @param j* @param @return 设定文件* @return double 返回类型* @throws*/public double distTo(int i, int j) {return dist[i][j];}public Iterable<Integer> pathTo(int i,int j){int[] p=prev[i];Stack<Integer> path=new Stack<Integer>();for(int m=j;m!=i;m=p[m]){path.push(m);}path.push(i);return path;}public static void main(String[] args) {// 不含负权重环的文本数据String text1 = "F:\\算法\\attach\\tinyEWDn.txt";// 含有负权重环的文本数据String text2 = "F:\\算法\\attach\\tinyEWDnc.txt";WeightDigraph g = new WeightDigraph(new In(text1));Johnson d = new Johnson(g);if (d.hasNegtiveCycle()) {System.out.println("该有向加权图含有负权重环,不存在最短路径");} else {int s = 0;for (int i = 0; i < g.v(); i++) {System.out.println("从原点" + s + "到" + i + "距离为" + d.distTo(s, i)+",路径为:");for(int m:d.pathTo(s, i)){System.out.print(m+"->");}System.out.println();}}}
}

如果采用负环图,打印结果为:

有负环,不存在最短路径...
该有向加权图含有负权重环,不存在最短路径

如果采用非负环图,打印结果为:

从原点0到0距离为0.0,路径为:
0->
从原点0到1距离为0.93,路径为:
0->2->7->3->6->4->5->1->
从原点0到2距离为0.26,路径为:
0->2->
从原点0到3距离为0.9900000000000001,路径为:
0->2->7->3->
从原点0到4距离为0.26000000000000023,路径为:
0->2->7->3->6->4->
从原点0到5距离为0.6100000000000001,路径为:
0->2->7->3->6->4->5->
从原点0到6距离为1.5100000000000002,路径为:
0->2->7->3->6->
从原点0到7距离为0.6000000000000001,路径为:
0->2->7->

转载于:https://my.oschina.net/u/1378920/blog/424028

算法导论——所有点对最短路径:稀疏图Johnson算法相关推荐

  1. 稀疏图Johnson算法

    在前面的文章<所有节点对的最短路径问题>中,我们介绍了用于稀疏图的Johnson算法,由于代码比较长,我们将其单独放在一篇文章之中. Johnson算法的时间复杂度在使用二叉堆作为最小优先 ...

  2. 算法导论之单源最短路径

    单源最短路径,在现实中是很多应用的,是图的经典应用,比如在地图中找出两个点之间的最短距离.最小运费等.单源最短路径的问题:已知图G=(V,E),找出给定源顶点s∈V到每个顶点v∈V的最短路径.单源最短 ...

  3. 算法导论——24.2 DAG最短路径算法java实现

    介绍 Bellman-Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题,但是对于DAG,可以有更加简化的算法去计算,使得时间复杂度更低. 针对DAG的特点,以拓扑排序为基础,提出了解 ...

  4. Dijkstra算法(堆优化版求稀疏图最短路)

    南昌理工acm集训队 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959年提出的,是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题. 基本思想 Dijkstra算法是用来解决不 ...

  5. 遍历所有点的最短路径python_图遍历算法之最短路径Dijkstra算法

    一.最短路径问题(shortest path problem) 最短路径问题是图论研究中一个经典算法问题,旨在寻找图中两节点或单个节点到其他节点之间的最短路径.根据问题的不同,算法的具体形式包括: 确 ...

  6. 所有结点对的最短路径问题之Johnson算法

    Johnson算法可以在O(V*V lgV + VE)的时间内找到所有节点对之间的最短路径,对于稀疏图来说,算法的渐进表现要由于重复平方法和FloydWarshall算法,如果图没有权值为负值的环路, ...

  7. 贪心算法之用优先队列解决最短路径问题(Dijkstra算法)

    1.问题 最短路径问题(Dijkstra算法)用 优先队列实现,问题描述和分析和优先队列先看前面我的几篇博客 贪心算法之最短路径问题(Dijkstra算法) C++之STL之priority_queu ...

  8. 【算法导论】第24章迪杰斯特拉算法

    1.问题引入 在带权有向图中求解某个源点到其余各个顶点的最短路径一般可以采用迪杰斯特拉算法(Dijkstra算法). 2.算法的主体思想: 引用:(http://hi.baidu.com/wangzi ...

  9. 【算法导论】学习笔记——第16章 贪心算法

    贪心算法是使做出的选择看起来都是当前最佳的,期望通过所做的局部最优选择来产生一个全局最优解.其实,这个定义旨在说明贪心算法必须伴随做出最优选择,如moving table,我们选择最大重叠数等等.当然 ...

最新文章

  1. Java类类getComponentType()方法与示例
  2. ZOJ 1760 How Many Shortest Path
  3. Python | 面试必问,线程与进程的区别,Python中如何创建多线程?
  4. c语言 更新学生信息,求学生信息管理系统C语言版
  5. Tokyo Tyrant优势
  6. Linux 修改环境变量
  7. 光流.flo文件生成.png图片(可批量)
  8. 安卓项目R,java文件不能自动更新,clean之后,R.java消失 (转自 Cynosure鱼)
  9. 蓝牙耳机测试软件apk_蓝牙耳机电量显示app下载
  10. 如果时间不够 ,无法进行充分的测试怎么办?
  11. c语言编程十进制转八进制算法,C语言十进制如何转八进制?
  12. cmd批处理文件格式
  13. 安装oracle显示无法解析的,1、pl/sql无法连接本机的oracle(ORA 12154:TNS:无法解析指定的连接标识符)解决方法:pl/sql不能安装在Program Files(...
  14. 锐捷交换机处理环路问题
  15. ES启动报错error downloading geoip database [GeoLite2-ASN.mmdb]
  16. 销售人员如何寻找客户?
  17. python爬虫实战三:近十年中国电影票房数据爬取与分析
  18. 使用Glade3.0进行界面开发
  19. 2.23 使用python解析.bag数据集(无需虚拟机和ROS)
  20. c mysql 返回字符串长度_objective-c中字符串长度计算

热门文章

  1. CISCO PIX/ASA Failover 技术初步学习
  2. Iphone是革了传统互联网的命
  3. 关于.NET技术体系的思维导图
  4. 人少,登录速度就是快.
  5. RunLoop深度探究以及有关面试题
  6. uitableviw 自适应高度
  7. ubuntu php上传文件,Ubuntu中增加apache上传文件大小限制(突破Aapache默认2M上传限制)...
  8. 网络入侵检测规避工具fragrouter
  9. 手机数据抓包入门教程
  10. Java中普通字符串转json_java普通对象和json字符串的互转