算法设计与分析 Ch08 图的深度优先遍历

8.1 图和图遍历

给定图 \(G=(V, E)\),V 是顶点集,边集 \(E \subseteq V \times V\) 表示顶点之间的某种二元关系。如果 \(E\) 是一种对称关系,则称图 \(G\) 为无向图;如果 \(E\) 是非对称关系,则称 \(G\) 为无向图。
用于图表示的数据结构主要有两种,一种是邻接链表,一种是邻接矩阵。
图遍历是对图的一种最基本但也是最重要的处理,它遵循节点之间的关联关系,按某种顺序依次处理图中所有的点和边。

8.2 有向图上的深度优先遍历

基本思想:从一个节点出发,如果它有未探索的邻居节点,则选择其中的某一个深入探索(其他可探索的节点暂时不管),每到一个新的节点则递归地进行上述深入探索的过程。当探索无法继续时,则沿着探索的路径回退。此时该节点可能还有其他邻居节点未被探索过,需要递归地对该邻居节点进行深入探索。

8.2.1 遍历框架

在遍历过程中一个节点会经历三种不同的状态,遍历算法将这三种状态标记为三种颜色:

  • 白色:表示一个节点尚未被遍历到。
  • 灰色:表示一个节点已经被遍历到,但是对于它的遍历尚未结束。这是因为根据深度优先遍历的规则,该节点还有若干邻居节点尚未遍历,当前算法正在递归地深入探索该节点地某个邻居节点。
  • 黑色:表示一个节点的所有邻居节点已经完成遍历,其自身的遍历也已经结束。

8.2.2 深度优先遍历树

由于图的一条边唯一地由它地一对顶点确定,因而考察一条边的两个顶点的状态变化组合时,可以进一步对边的状态做更细致的分类。深度优先的遍历过程将边分为四种类型:Tree Edge、Back Edge、Descendant Edge、Cross Edge。

8.2.3 活动区间

Def 8.1(活动区间) 在遍历过程中,一个节点的活动区间定义为从该节点被发现到遍历结束的时间区间。

Thm 8.1 考察深度优先遍历图 \(G=(V, E)\) 的过程。对任意点 \(v\)\(w\)

  • \(w\)\(v\) 在 DFS 树中的后继节点,当且仅当 \(active(w) \subseteq active(v)\)。若 \(w \ne v\),则此处的包含为真包含
  • \(w\)\(v\) 没有祖先后继关系,当且仅当 \(active(w)\)\(active(v)\) 没有重叠。
  • 如果 \(vw\) 是图 \(G\) 中的边,则
    • \(vw\) 是 CE,当且仅当 \(active(w)\)\(active(v)\) 前面。
    • \(vw\) 是 DE,当且仅当存在第三个节点 \(x\) 满足:\(active(w) \subset active(x) \subset active(v)\)
    • \(vw\) 是 TE,当且仅当 \(active(w) \subset active(v)\),且不存在第三个节点 \(x\) 满足:\(active(w) \subset active(x) \subset active(v)\)
    • \(vw\) 是 BE,当且仅当 \(active(v) \subset active(w)\)

基于此定理,可以将图遍历活动间的时序关系等价地转换成整数区间之间的先后/包含关系。

Thm 8.2(白色路径定理) 在深度优先遍历树中,节点 \(v\)\(w\) 的祖先,当且仅当在遍历过程中刚刚发现 \(v\) 的时刻,存在一条从 \(v\)\(w\) 的全部由白色节点组成的路径。

8.3 有向图上深度优先遍历的应用

8.3.1 拓扑排序

Def 8.2(拓扑排序) 如果为图中每个顶点 \(v_1, v_2, \dots , v_n\) 分配一个序号 \(\tau_1, \tau_2 ,\dots , \tau_n\) 满足:

  • 所有序号为正整数 1 到 n 的某个排列(理论上是全序集即可)
  • 对任意有向边 \(i \to j\)(从 \(v_i\) 指向 \(v_j\) 的有向边),满足 \(\tau_i \lt \tau_j\)
    \(\tau_1, \tau_2 ,\dots , \tau_n\) 为图 \(G\) 中顶点 \(v_1, v_2, \dots , v_n\) 的一个拓扑排序。(若要求 \(\tau_i \lt \tau_j\) 则成为逆拓扑排序)。

拓扑排序只限制有向边的两个节点上序号的大小关系,通过传递性来保证整个图上的“拓扑关系”。

Lemma 8.1 如果有向图 \(G=(V, E)\) 中有环,则图 \(G\) 不存在拓扑排序。

反证可推出环上任意节点的拓扑序号都严格大于自身。
此引理揭示了有向图中环的存在性与拓扑排序的存在性之间的重要关联。

Lemma 8.2 如果有向图 \(G=(V, E)\) 为有向无环图,则图 \(G\) 必然存在拓扑排序。

Thm 8.3\(G\) 是有向无环图,当且仅当图 \(G\) 有拓扑排序。

8.3.2 关键路径

拓扑排序关注的是一类简单的调度问题,即主要考虑任务之间的依赖关系,在保证依赖关系的前提下所有任务串行执行。以此为基础可以变得更加复杂。例如考虑有多台机器并行、每个任务有自己的执行时长等等。任务调度的目标是让所有任务尽早执行完。

Def 8.3(最早开始时间、最早结束时间的递归定义)

  • 如果一个任务 \(a_i\) 不依赖任何其他任务,则 \(est_i=0\)
  • 如果一个任务 \(a_i\)\(est_i\) 已经被确定,则 \(eft_i=est_i + l_i\)
  • 如果一个任务 \(a_i\) 依赖若干其他任务,则 \(est_i\) 为它所依赖的所有任务的最早结束时间中的最大值:\(est_i = max \{ eft_j \mid a_i \to a_j \}\)

Def 8.4(关键路径) 任务调度中的关键路径是一组任务 \(v_0, v_1, \dots, v_k\) 满足:

  • 任务 \(v_0\) 不依赖其他任何任务
  • 对任意 \(1 \le i \le k:\) \(v_i\to v_{i - 1}, est_i = eft_{i - 1}\)
  • 任务 \(v_k\) 的最早结束时间是所有任务的最早结束时间中最大的

关键路径决定所有任务全部处理完毕所需的最少时间。
最早开始时间和最早结束时间的递归定义,决定了它们和有向图中逻辑尽头的概念紧密关联。

8.3.3 有向图中的强连通片

Def 8.5(强连通片、收缩图) 定义一个有向图中两个节点是强连通的,如果它们互相可达。定义一个有向图是强连通的,如果其任意两个节点之间互相可达。有向图的强连通片是其极大强连通子图。如果把图 \(G\) 中每个强连通片收缩成一个点,强连通片之间的边收缩成一条有向边,则得到 \(G\) 的收缩图 \(G\downarrow\)

Def 8.6(有向图的转置) 将图 G 中的所有边同时调转方向,则得到 \(G\) 的转置图 \(G^T\)。从邻接矩阵的角度来说,将图 G 的邻接矩阵转置,则得到 \(G^T\) 的邻接矩阵。

SCC 算法:

  • 遍历结束时标记尽头:尽头强连通片通过深度优先遍历来标识。每个节点在遍历结束前记录自己成为(逻辑)尽头。
  • 先进后出的栈结构:每个节点完成处理时,进入一个节点栈。
  • 图的转置:第一轮遍历后得到了栈,在此基础上进行第二轮遍历。首先图进行转置,然后从节点栈中依次取出节点开始第二轮遍历,完成强连通片的标记。

Def 8.7(强连通片的首节点) 在第一轮深度优先遍历过程中,定义每个强连通片中第一个被发现的节点为该强连通片的首节点。

Inf 8.1 考察一个强连通片中的所有节点,首节点就是第一个被发现的,同时也是最后一个结束遍历的。这可以等价地表述为,首节点的活动区间包含同一个强连通片中其他所有节点的活动区间。

Lemma 8.3 第一轮遍历的遍历树中,可能包括一个或多个强连通片的节点。也就是说,一个强连通片中的节点不可能一部分在某棵遍历树中,一部分不在。

Lemma 8.4 当某个强连通片的首节点在第一轮遍历中被发现时(刚刚被发现,即将被染为灰色时),不可能有路径通向某个灰色节点。

Lemma 8.5 假设 \(l\) 是某个强连通片的首节点,\(x\) 是另一个强连通片中的节点,并且存在 \(l\) 通向 \(x\) 的路径,则在第一轮遍历中 \(x\)\(l\) 先结束遍历,即 \(x.finishTime \lt l.finishTime\)

Lemma 8.6 在第二轮深度优先遍历过程中,当一个白色节点从栈中被 POP 出来时,它一定是其所在强连通片的首节点。

Thm 8.4 SCC 算法是正确的。

8.4 无向图上深度优先遍历

8.4.1 无向图的深度优先遍历树

遍历过程中,节点的三种状态(染色)不变,每个节点同样是不可逆转地由白色变成灰色,最终变成黑色。但是由于边的无向特性,遍历过程中对于边的标记与有向图的情况相比有一些重要变化:

  • TE:当发现一个白色节点并递归地进行遍历时,算法就将连接该白色节点的边标记为 TE,遍历过程中的 TE 组成遍历树,这一情形与有向图是类似的。
  • BE:当遍历点 \(u\) 并发现一条边指向灰色节点 \(v\) 时,此时有两种不同的情况:
    • -如果 \(vu\) 是 TE,即在遍历点 \(v\) 时,发现白色邻居 \(u\),并递归地对 \(u\) 进行遍历。
    • 如果 \(v\)\(u\) 的某个不是父亲节点的祖先节点,则算法将 \(uv\) 标记为 BE。
  • DE:当遍历点 \(u\) 时,发现一条边指向节点 \(v\),并且 \(v\)\(u\) 在遍历树中的后继节点,此时边 \(uv\) 为 DE,但是这次遍历必然是二次遍历,应该被剔除。
  • CE:在遍历无向图时,CE 不可能存在,因而在分析遍历过程时可以直接剔除这一情况。

8.4.2 无向图的深度优先遍历框架

一个邻居节点只可能有三个颜色:

  • 白色:这一情况已经在算法框架中进行了处理。
  • 灰色:灰色邻居节点又分为两种情况:
    • 灰色且不是父节点:这一情况已经在算法框架中进行了处理。
    • 灰色且是父节点:这一情况算法框架中没有处理。根据上面的分析,此时是二次遍历,无需进行处理。
  • 黑色:对黑色的邻居节点的遍历只可能对应两种边。

8.5 无向图上深度优先遍历的应用

8.5.1 容错连通

Def 8.8(\(k-\)点连通,\(k-\)边连通) 对于连通的无向图 \(G\),如果其中任意去掉 \(k-1\) 个点,图 \(G\) 仍然连通,则称图 \(G\)\(k-\) 点连通的。类似地,可得 \(k-\) 边连通定义。

Def 8.9(割点和桥) 对于一个连通的无向图 \(G\),称节点 \(v\) 为割点,如果去掉点 \(v\) 后,图 \(G\) 不再连通;称边 \(uv\) 为桥,如果去掉边 \(uv\) 后,图 \(G\) 不再连通。

8.5.2 寻找割点

Lemma 8.7(割点的基于路径的定义) 点 \(v\) 为割点,当且仅当点对 \(w\)\(x\) 满足如下性质:点 \(v\) 出现在 \(w\)\(x\) 的所有路径上。

Lemma 8.8(割点的基于深度优先遍历的定义) 假设在一次深度优先遍历中,点 \(v\) 不是遍历树的根节点,则点 \(v\) 为割点,当且仅当在遍历树中,存在点 \(v\) 的某个子树,没有任何 BE 指向 \(v\) 的祖先节点。

Thm 8.5 ARTICULATION-POINT-DFS 算法是正确的。

8.5.3 寻找桥

Lemma 8.9 (桥的基于深度优先遍历的定义) 给定遍历树中 TE 的边 \(uv\)\(u\)\(v\) 的父节点),\(uv\) 是桥,当且仅当以 \(v\) 为根的所有遍历树子树中没有 BE 指向 \(v\) 的祖先(不包括 \(v\),包括 \(u\))。

posted @ 2023-01-14 14:14  PTCGnaya  阅读(92)  评论(0编辑  收藏  举报