本文作者为: SylvanasSun.转载请务必将下面这段话置于文章开头处(保留超链接).
本文转发自SylvanasSun Blog,原文链接: https://sylvanassun.github.io/2017/07/23/2017-07-23-Graph_DirectedGraphs/
有向图的性质
有向图
与无向图
不同,它的边
是单向的,每条边所连接的两个顶点都是一个有序对,它们的邻接性是单向的.
在有向图
中,一条有向边
由第一个顶点
指出并指向第二个顶点
,一个顶点
的出度
为由该顶点
指出的边
的总数;一个顶点
的入度
为指向该顶点
的边的总数.
v->w
表示一条由v
指向w
的边,在一幅有向图
中,两个顶点
的关系可能有以下四种(特殊图除外):
- 没有
边
相连.
- 存在一条从
v
到w
的边
:v->w
.
- 存在一条从
w
到v
的边
:w->v
.
- 既存在
v->w
,也存在w->v
,也就是一条双向边
.
当存在从v
到w
的有向路径
时,称顶点w
能够由顶点v
达到.但在有向图
中,由v
能够到达w
并不意味着由w
也能到达v
(但每个顶点
都是能够到达它自己的).
有向图的实现
有向图
的实现与无向图
差不多,只不过在边
的方向上有所不同.(本文中的所有完整代码可以在我的GitHub中查看)
|
|
可达性
对于”是否存在一条从集合中的任意顶点
到达给定顶点v
的有向路径?”等类似问题,可以使用深度优先搜索
或广度优先搜索
(与无向图
的实现一致,只不过传入的图
的类型不同),有向图
生成的搜索轨迹甚至要比无向图
还要简单.
对于可达性分析
的一个典型应用就是内存管理系统.例如,JVM
使用多点可达性分析
的方法来判断一个对象
是否可以进行回收: 所有对象
组成一幅有向图
,其中有多个Root顶点
(它是由JVM
自己决定的)作为起点
,如果一个对象
从Root顶点
不可达,那么这个对象
就可以进行回收了.
环
在与有向图
相关的实际应用中,有向环
特别的重要.我们需要知道一幅有向图
中是否包含有向环
.在任务调度问题或其他许多问题中会不允许存在有向环
,所以对于环
的检测是很重要的.
使用深度优先搜索
解决这个问题并不困难,递归调用隐式使用的栈表示的正是”当前”正在遍历的有向路径
,一旦找到了一条边v->w
且w
已经存在于栈中,就等于找到了一个环
(栈表示的是一条由w
到v
的有向路径
,而v->w
正好补全了这个环
).
|
|
拓扑排序
拓扑排序
等价于计算优先级限制下的调度问题的,所谓优先级限制的调度问题即是在给定一组需要完成的任务与关于任务完成的先后次序的优先级限制,需要在满足限制条件的前提下来安排任务.
拓扑排序
需要的是一幅有向无环图
,如果这幅图
中含有环
,那么它肯定不是拓扑有序
的(一个带有环的调度问题是无解的).
在学习拓扑排序
之前,需要先知道顶点
的排序.
顶点排序
使用深度优先搜索
来记录顶点排序
是一个很好的选择(正好只会访问每个顶点
一次),我们借助一些数据结构
来保存顶点排序
的顺序:
- 前序: 在递归调用之前将
顶点
加入队列.
- 后序: 在递归调用之后将
顶点
加入队列.
- 逆后序: 在递归调用之后将
顶点
压入栈.
|
|
拓扑排序的实现
所谓拓扑排序
就是无环有向图
的逆后序
,现在已经知道了如何检测环
与顶点排序
,那么实现拓扑排序
就很简单了.
|
|
强连通性
在一幅无向图
中,如果有一条路径连接顶点v
和w
,则它们就是连通
的(既可以从w
到达v
,也可以从v
到达w
).但在有向图
中,如果从顶点v
有一条有向路径到达w
,则w
是从v
可达的,但从w
到达v
的路径可能存在也可能不存在.
强连通性
就是两个顶点v
和w
是互相可达的.有向图
中的强连通性
具有以下性质:
- 自反性: 任意
顶点v
和自己都是强连通性
的(有向图
中顶点都是自己可达的).
- 对称性: 如果
v
和w
是强连通的,那么w
和v
也是强连通的.
- 传递性: 如果
v
和w
是强连通的且w
和x
也是强连通的,那么v
和x
也是强连通的.
强连通性
将所有顶点
分为了一些等价类,每个等价类都是由相互为强连通的顶点
的最大子集组成的.这些子集称为强连通分量
,它的定义是基于顶点的,而非边.
一个含有V
个顶点的有向图
含有1 ~ V
个强连通分量
.一个强连通图
只含有一个强连通分量
,而一个有向无环图
中则含有V
个强连通分量
.
Kosaraju算法
Kosaraju算法是用于枚举图中每个强连通分量
内的所有顶点,它主要有以下步骤:
- 在给定一幅
有向图
$G$中,取得它的反向图$G^R$.
- 利用
深度优先搜索
得到$G^R$的逆后序排列.
- 按照上述逆后序的序列进行
深度优先搜索
- 同一个
深度优先搜索
递归子程序中访问的所有顶点
都在同一个强连通分量
内.
|
|
传递闭包
在一幅有向图G
中,传递闭包
是由相同的一组顶点
组成的另一幅有向图
,在传递闭包
中存在一条从v
指向w
的边且仅当在G
中w
是从v
可达的.
由于有向图
的性质,每个顶点
对于自己都是可达的,所以传递闭包
会含有V
个自环.
通常将传递闭包
表示为一个布尔值矩阵,其中v
行w
列的值为true
代表当且仅当w
是从v
可达的.
传递闭包
不适合于处理大型有向图
,因为构造函数所需的空间与$V^2$成正比,所需的时间和$V(V+E)$成正比.
|
|