首页 理论教育深度优先搜索在形式化构件装配中的应用

深度优先搜索在形式化构件装配中的应用

【摘要】:在实际应用中,很多算法都体现了深度优先搜索的思想。图3-2 有向图的邻接表表示2.拓扑排序深度优先搜索的另一个经典应用是对有向无环图进行拓扑排序。这两次深度优先搜索一次运行在图G上,一次运行在转置图GT上。算法计算的结果是深度优先森林,每一个强连通分量对应一棵深度优先树。

许多图算法在一开始都会先通过搜索来获得图的结构,其他的一些图算法则是对基本的搜索加以优化。在实际应用中,很多算法都体现了深度优先搜索的思想。可以说,图的搜索是整个图算法的核心。以下是图的深度优先搜索算法的几个经典的应用。

1.邻接表的创建

对于一个图来说,进行其他操作的前提是要对图运用某种方法表示出来。目前,有两种方法可以对图进行表示——邻接表和邻接矩阵。两种表示方法既可以表示无向图,也可以表示有向图。如果想要建立一个图的邻接表,需要对图中的节点进行遍历,可以采用深度优先搜索对节点进行遍历,然后在进行深度优先遍历的同时,将与节点u所有相邻的节点添加到以该节点为表头的单链表当中去。这样,我们便可以利用深度优先搜索的思想建立一个图的邻接表。一个有向图的邻接表表示如图3-2所示。

图3-2  有向图的邻接表表示

2.拓扑排序

深度优先搜索的另一个经典应用是对有向无环图进行拓扑排序。如果要对图进行拓扑排序,则要求该图必须是有向无环图。拓扑排序其实就是对一个图中的所有节点进行先后顺序的一个排列。假设在一个有向图G中,节点u是节点v的前驱节点,则在拓扑排序中,节点v在节点u的后面。我们可以简单地把拓扑排序理解为:图中的所有节点都在一条垂直线上按照先后顺序排列好,而边则从上指向下。

在我们的实际生活中,很多事情都需要运用到拓扑排序,如:用拓扑排序表示制作一个生日蛋糕各个步骤之间的先后次序。图3-3描述的是一个人每天早上起床穿衣所发生的事件的次序图。某些服饰必须在穿好其他服饰之后才能穿,比如鞋子必须要在穿好袜子之后再穿。而有些服饰则可以以任意顺序穿上,比如袜子和裤子之间可以以任意次序进行穿戴。对该图进行拓扑排序所获得的就是一种合理穿衣的次序。

图3-3  拓扑排序实例

下面的简单算法是借助深度优先遍历来实现拓扑排序,这个时候需要使用到栈结构来记录拓扑排序的结果。(www.chuimin.cn)

3.强连通分量的求解

将有向图分解为强连通分量也可以使用深度优先搜索来实现。将图分解为强连通分量是许多针对有向图算法操作的开始。在将图分解为强连通分量后,这些算法将分别运行在每个连通分量上,然后根据连通分量之间的连接结构将各个结果组合起来,从而获得最终所需的结果。

设有向图G=(V,E)的强连通分量是一个最大节点集合C,对于该集合中的任意一对节点u和v来说,路径u到v和路径v到u同时存在,也就是说,节点u和节点v可以互相到达。如在图3-4中,子图{1、2、5}是一个强连通分量,{3、4}、{6、7}、{8}也是一个强连通分量。

图3-4  有向图G

运用算法STRONGLY-CONNECTED-COMPONENTS能够正确计算出有向图G的强连通分量:

在上述寻找强连通分量的算法中,需要用到图G的转置GT=(V,ET),这里ET={(u,v):(v,u)∈E},即ET由对图G中的边进行反向而获得。上述算法使用两次深度优先搜索来计算有向图G=(V,E)的强连通分量。这两次深度优先搜索一次运行在图G上,一次运行在转置图GT上。算法计算的结果是深度优先森林,每一个强连通分量对应一棵深度优先树。