有向无环图的最短路径

我们已经知道了如何通过Dijkstra算法在非负权图中找到最短路径。即使图中有负权边,我们也知道通过Bellman-Ford算法找到一个从 给定的源点到其它所有节点的最短路径。现在我们将看到一个在线性时间内运行得更快的算法,它可以在有向无环图中找到从一个给定的源点到其它所有可达顶点的 最短路径,又名有向无环图(DAG)。

由于有向无环图无环所以我们不必担心负环的问题。正如我们已经知道在负环里讨论最短路径是毫无意义的一样,因为我们可以在这些环里不断“循环”,但实际上我们得到的路径将变得越来越短(构成负的环路,存在死循环)。

负环的存在使我们试图找到最短路径的行为变得毫无意义!

因此,我们要解决Dijkstra算法和的Bellman-Ford算法中的两个问题。首先,我们只需要非负的权重,其次,图中不能有环。好了,这样我们就可以通过这个算法处理满足这两种情况的例子了。

概述

关于有向无环图(DAGs)我们首先要知道,它们可以很容易地进行拓扑排序。拓扑排序应用范围非常之广,其中最常用的或许就是用于安排依赖任务(依赖任务是同属于一个工作中相同任务的实体,这些实体是保证互连的,它们解决共同的问题)。

拓扑排序通常是用来“排序”依赖任务的!

经过拓扑排序,我们最终会得到一张DAG图的顶点列表,我们确信在拓扑排序列表中如果存在一条边(u,v),那么顶点u会先于顶点v进入列表中。

如果有一条边(u,v),那么顶点u一定在顶点v前面。这个结果通过这张图片变得更加通俗易懂。其中B和D之间没有边,但在列表中B在D前面!

此信息异常重要,我们唯一需要做的事情就是通过这个排序列表来计算距离最短的路径,这和Dijkstra算法比较相似。

好了,让我们来总结一下这个算法:

-首先,我们必须对有向无环图进行拓扑排序;

-其次,我们将到源点的距离初始化为0并将到其它所有顶点的距离设置为无穷大;

-最后,对于列表中的每一个顶点,我们从它的所有邻节点中找到最短路径的那个顶点;

这很像Dijkstra算法,但是其主要区别是我们使用了一个优先级队列,并且此次我们使用的是经过拓扑排序的列表。

代码

此次的代码实际上是一段伪代码。虽然目前为止所有的例子都是用PHP编写,但是伪代码更易于理解,也不会将你与某一特定的语言实现绑定在一起。此外,如果你对给定的语言感到难以理解,那么对你而言读懂代码比阅读伪代码更加困难。


1

2

3

4

5

6

7

Topologically sort G into L;

Set the distance to the source to 0;

Set the distances to all other vertices to infinity;

For each vertex u in L

   - Walk through all neighbors v of u;

   - If dist(v) > dist(u) + w(u, v)

      - Set dist(v) <- dist(u) + w(u, v);

应用

我们必须使用这种算法的原因显而易见。唯一值得注意的问题是我们必须确保这个图没有环。但是,如果我们知道如何建立图,那么我们或多或少会有一些附加信息来确认这个图中是否有环 – 那么此时这个线性时间内的算法就会非常适用。

转载 http://www.importnew.com/9690.html

有向无环图的最短路径

时间: 2024-10-08 02:27:51

有向无环图的最短路径的相关文章

算法导论——有向无环加权图的最短路径

package org.loda.graph; import org.loda.structure.Stack; import org.loda.util.In; /** * * @ClassName: NoCycleSP * @Description: 有向无环图的最短路径算法 * * 无环图可以采用拓扑排序来处理,进行拓扑排序中不会有排名靠后的指向排名靠前的情况,所以拓扑排序的第一个节点是无法从其他节点抵达的 * * 无环权重有向图的算法时间复杂度可以高达O(V+E),比Dijkstra算法

javascript实现有向无环图中任意两点最短路径的dijistra算法

有向无环图 一个无环的有向图称做有向无环图(directed acycline praph).简称DAG 图.DAG 图是一类较有向树更一般的特殊有向图, dijistra算法 摘自 http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijk

【数据结构】拓扑排序、最短路径算法、Dijkstra算法、无环图等等

图的定义 图(graph)G = (V,E)由顶点(vertex)的集V和边(Edge)的集E组成.有时也把边称作弧(arc),如果点对(v,w)是有序的,那么图就叫做有向的图(有向图).顶点v和w邻接(adjacent)当且仅当(v,w)属于E. 如果无向图中从每一个顶点到其他每个顶点都存在一条路径,则称该无向图是连通的(connected).具有这样性质的有向图称为是强连通的(strongly connected).如果有向图不是强连通的,但它的基础图(underlying graph)(也

[从今天开始修炼数据结构]无环图的应用 —— 拓扑排序和关键路径算法

上一篇文章我们学习了最短路径的两个算法.它们是有环图的应用.下面我们来谈谈无环图的应用. 一.拓扑排序 博主大学学的是土木工程,在老本行,施工时很关键的节约人力时间成本的一项就是流水施工,钢筋没绑完,浇筑水泥的那帮兄弟就得在那等着,所以安排好流水施工,让工作周期能很好地衔接就很关键.这样的工程活动,抽象成图的话是无环的有向图. 在表示工程的有向图中,用顶点表示活动,弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,成为AOV网(Active On Vertex Network) ※ 若在

UVA10305 Ordering Tasks(有向无环图排序--toposort) Kahn算法

题目描述:https://vjudge.net/problem/UVA-10305 题目分析: 恨水的题目,只要学了toposort就会做的,大概意思是给你n个变量,m个不等关系表示a<b,问n个数可能的关系;不如举个例子例如n=3表示3个变量我们假如他们是a,b,c现在有两个关系a<b,a<c 那么输出有两种a<b<c或者a<c<b(题目要求输出任意一种); 题目大概就这个意思,那么我们怎么做呢,我们想一想如果把变量看成点,关系看成有向边,那么就得到一个图,这个

图的邻接表表示与无环图的拓扑排序

一.  图的最常用的表示方法是邻接矩阵和邻接表. 1,邻接矩阵 邻接矩阵其实就是一个二维数组,对于每条边<u,v>,我们就令A[u][v] = 1,如果图为有权图,我们也可以令A[u][v]等于该权,这么表示的优点是非常简单,但是它的空间需求很大,如果图是稠密的,邻接矩阵是合适的表示方法,如果图是稀疏的,那这种方法就太浪费空间了,下面给出图的邻接矩阵表示例子. 2 邻接表 邻接表是图的常用储存结构之一.邻接表由表头结点和表结点两部分组成,其中图中每个顶点均对应一个存储在数组中的表头结点.如下图

HDU 3249 Test for job (有向无环图上的最长路,DP)

 解题思路: 求有向无环图上的最长路,简单的动态规划 #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <vector> #include <cmath> #define LL long long using namespace std; const int

48. 蛤蟆的数据结构笔记之四十八的有向无环图的应用关键路径

48. 蛤蟆的数据结构笔记之四十八的有向无环图的应用关键路径 本篇名言:"富贵不淫贫贱乐 ,男儿到此是豪雄.-- 程颢" 这次来看下有向无环图的另一个应用关键路径. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47135061 1.  关键路径 与AOV-网相对应的是AOE-网(Activity On Edge)即边表示活动的网.AOE-网是一个带权的有向无环图,其中,顶点表示事件(Event),弧表示活动,权表

有向无环图的最小路径覆盖 二分图模型解题

有向无环图中,路径覆盖就是在图中找一些路径,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联(如果把这些路径中的每条路径从它的起始点走到它的终点,那么恰好可以经过图中的每个顶点一次且仅一次). 最小路径覆盖就是找出最小的路径条数,使之成为原图的一个路径覆盖. 公式:最小路径覆盖=(原图)顶点数-对应的二分图的最大匹配数. 我们通过例题来解释如何把DAG转换为二分图模型. HDU1151Air Raid 题目大意:在一个城镇,有n个路口,和m条单向路,而且这些路不会形成环.现在要弄