• 周蓬安.blog的博客—强国博客—人民网 2019-05-10
  • 紫光阁中共中央国家机关工作委员会 2019-05-10
  • 感触名家笔下的端午文化吃香粽原来可以这样文艺 2019-05-09
  • 追梦夺冠游行嘲讽詹皇 百万人面前穿订制T恤羞辱他 2019-04-27
  • 《瘟疫传说》:黑死病恐怖 姐弟在绝望中求生 2019-04-10
  • 陕西国防工业职业技术学院百名大学生志愿者敬老院慰问孤寡老人陕西国防工业职业技术学院百名大学生志愿者敬老院慰问-陕西教育新闻 2019-04-08
  • 西藏拉萨:新家园 新生活 2019-04-08
  • 尊重和保障宗教信仰自由的中国实践 2019-04-06
  • 一敬泯恩仇 俄罗斯队主帅这个动作太暖了 2019-03-20
  • 四大名著剧组首次同台忆往事 经典影视剧如何铸就? 2018-12-07
  • “天眼”凝望 探秘宇宙 2018-12-07
  • 0

    最短路径算法总结

    Posted by 撒得一地 on 2016年5月3日 in 杂谈
    国外稳定加速器推荐    Express | Vypr

    前言

    因为我在跟Robert Sedgewick的Algorithms,所以本文和前面几篇算法文章一样,都是基于这门课的梳理总结,并加以自己理解,这种学习方式其实效率还挺高的。

    最短路径算法

    最短路径问题有多种情况可以讨论

    给定起点的最短路径问题
    给定终点的最短路径问题
    给定起点和终点的最短路径,也就是求任意两点之间的最短路径问题
    本文只讨论单源起点问题,有如下三个算法可以解决这个问题。

    Dijkstra //适用于无负权重
    Topological sort //适用于无环
    Bellman-Ford //适用于无负环

    Dijkstra

    对于不含负权的有向图,这是目前已知的最快的单源最短路径算法

    比较有意思的是,这个算法可以说就是prim算法。只不过就是比较的依据从相对于整棵树变成了源点

    所以,原理依旧是贪心算法,保证每一步都是最短。这里需要用优先队列来保存边。

    步骤

    初始化所有顶点到源点的路径为无限大
    顶点插入优先队列
    出队一个点
    对所有与这个点相关联的边进行放松操作
    重复3
    所谓的放松操作,就是一个比较的过程,若比原来的距离更短即进队。

    代码

    可以看到下面的代码基本上和Prim一致。

    	// @author Robert Sedgewick @author Kevin Wayne
    	public DijkstraSP(EdgeWeightedDigraph G, int s) {
    	       for (DirectedEdge e : G.edges()) {
    	           if (e.weight() < 0)
    	               throw new IllegalArgumentException("edge " + e + " has negative weight");
    	       }
    
    	       distTo = new double[G.V()];
    
    	       edgeTo = new DirectedEdge[G.V()];
    
    	       for (int v = 0; v < G.V(); v++)
    	           distTo[v] = Double.POSITIVE_INFINITY;
    
    	       distTo[s] = 0.0;
    
    	       // relax vertices in order of distance from s
    	       pq = new IndexMinPQ<Double>(G.V());
    	       pq.insert(s, distTo[s]);
    	       while (!pq.isEmpty()) {
    	           int v = pq.delMin();
    	           for (DirectedEdge e : G.adj(v))
    	               relax(e);	       }
    
    	   }
    
    	   // relax edge e and update pq if changed
    	   private void relax(DirectedEdge e) {
    	       int v = e.from(), w = e.to();
    
    	       if (distTo[w] > distTo[v] + e.weight()) {
    	           distTo[w] = distTo[v] + e.weight();
    	           edgeTo[w] = e;
    	           if (pq.contains(w)) pq.decreaseKey(w, distTo[w]);
    	           else                pq.insert(w, distTo[w]);
    	       }
    	   }
    

    关于Dijkstra为什么不能含有负权值

    可以想象一下,如果有一条负边在图中。Dijkstra维护的优先队列,每次都是取一条最小的边出来的,而这条负边,可以使这条路无限小。

    	private void relax(DirectedEdge e) {
    	       int v = e.from(), w = e.to();
    
    	       if (distTo[w] > distTo[v] + e.weight()) {   //若是负边的话每次都会减小,就会不断进入优先队列?。?!
    	           distTo[w] = distTo[v] + e.weight();  
    
    	           edgeTo[w] = e;
    
    	           if (pq.contains(w)) pq.decreaseKey(w, distTo[w]);
    	           else                pq.insert(w, distTo[w]);
    	       }
    	   }
    

    效率

    Dijkstra效率取决于优先队列的效率。二叉堆的话效率为O(ElogV)

    Topological sort

    这种方法实现简单,效率也高,但只适用于无环图,权值可以为负。

    步骤

    初始化所有顶点到源点的路径为无限大
    对顶点进行拓扑排序
    按照顶点顺序,对每条相关的边进行放松

    代码

    	Topological topological = new Topological(G);
    
    	if (!topological.hasOrder())
    	    throw new IllegalArgumentException("Digraph is not acyclic.");
    
    	for (int v : topological.order()) {
    	    for (DirectedEdge e : G.adj(v))
    	        relax(e);
    	}
    

    效率

    Topological sort algorithm computes SPT in any edgeweighted
    DAG in time proportional to E + V

    Bellman-Ford

    对于无负环的图一种解决方案。最直接的实现是对所有边进行V-1次放松,但是效率太低。复杂度高达O(V*E)

    for (int i = 0; i < G.V(); i++)
        for (int v = 0; v < G.V(); v++)
            for (DirectedEdge e : G.adj(v))
                relax(e);

    优化

    原始的版本总共进行V-1次放松,但其实,后面的很多次都是无效的放松,实际中不到V-1次就已经放松完全了。判断依据就是distTo[v]有无变化。

    这种方法时间复杂度最坏情况依旧是O(V*E),平均情况已经快很多了O(E+V)

    Reference

    算法4th

    维基百科

    原文地址://threezj.com/2016/05/02/最短路径算法总结/

    上一篇:

    下一篇:

    相关推荐

    发表评论

    电子邮件地址不会被公开。 必填项已用*标注

    2 + 6 = ?

    网站地图|广东快乐10分开奖直播

    Copyright © 2015-2019 广东快乐10分开奖直播 All rights reserved.
    闽ICP备15015576号-1,版权所有?psz.

  • 周蓬安.blog的博客—强国博客—人民网 2019-05-10
  • 紫光阁中共中央国家机关工作委员会 2019-05-10
  • 感触名家笔下的端午文化吃香粽原来可以这样文艺 2019-05-09
  • 追梦夺冠游行嘲讽詹皇 百万人面前穿订制T恤羞辱他 2019-04-27
  • 《瘟疫传说》:黑死病恐怖 姐弟在绝望中求生 2019-04-10
  • 陕西国防工业职业技术学院百名大学生志愿者敬老院慰问孤寡老人陕西国防工业职业技术学院百名大学生志愿者敬老院慰问-陕西教育新闻 2019-04-08
  • 西藏拉萨:新家园 新生活 2019-04-08
  • 尊重和保障宗教信仰自由的中国实践 2019-04-06
  • 一敬泯恩仇 俄罗斯队主帅这个动作太暖了 2019-03-20
  • 四大名著剧组首次同台忆往事 经典影视剧如何铸就? 2018-12-07
  • “天眼”凝望 探秘宇宙 2018-12-07
  • 重庆幸运农场开奖号码 高频老时时彩 经营彩票网站 足彩 晓风彩票网 秒速时时彩精准计划 北京pk10是违法赌博吗 快乐8开奖直播 win310彩客网 彩票开奖15选5贵州 极速快三走势-极速快3 体彩p5跨度走势图带连线 老时时彩最近开奖号码 中国福彩网3d太湖字谜 云南时时彩中和值走势 北京赛车pk10官方