📜  图的拓扑排序使用顶点的离开时间(1)

📅  最后修改于: 2023-12-03 14:50:49.449000             🧑  作者: Mango

图的拓扑排序使用顶点的离开时间

什么是拓扑排序?

拓扑排序是一个有向无环图(DAG)中所有顶点的线性序列。对于图中的任意两个顶点,如果存在一条从第一个顶点到第二个顶点的路径,那么在序列中,第一个顶点出现在第二个顶点的前面。用途是在进行有先后关系的任务时,可以根据任一合法的拓扑序列来制定一个合理的工作计划。

使用顶点的离开时间进行拓扑排序

在深度优先搜索的过程中,每个点会有三个时间戳:发现时间(discovery time)、结束时间(finishing time)以及点的过程时间(process time)。

在图的遍历过程中,当一个点的所有出边都被遍历过之后,这个点被标记为已经完成(也称「离开」)。这个时间被称为该点的结束时间。关于发现时间,是指在搜索中第一次遍历到该点的时间。

对于任一有向图,在 DFS 树中,一个节点的结束时间总是在它的子节点后面,而这个性质就能够协助我们完成拓扑排序的过程。

具体来说,在 DFS 过程中,每个完成点的结束时间都要被记录下来。当所有的结束时间被记录完毕后,再按照每个点的结束时间(从大到小)进行排序,所得到的顺序就是一个拓扑序列。

下面是使用 Python 语言实现的拓扑排序算法:

# 拓扑排序算法
def top_sort(G):
    n = len(G)
    visited = [False] * n
    topo_order = [None] * n
    index = n - 1
    for u in range(n):
        if not visited[u]:
            index = dfs(G, visited, topo_order, u, index)
    return topo_order

# DFS步骤
def dfs(G, visited, topo_order, u, index):
    visited[u] = True
    for v in G[u]:
        if not visited[v]:
            index = dfs(G, visited, topo_order, v, index)
    topo_order[index] = u
    index -= 1
    return index

其中,输入的图 G 应该是以邻接表的形式存储的,top_sort 函数中的 visited 数组是用来标记各个点是否已经被访问过的,topo_order 数组用来记录各个点的拓扑序列。dfs 函数就是标准的深度优先搜索算法,通过递归遍历所有节点,并记录它们的拓扑排序。

总结

利用图的拓扑排序可以将一个有先后关系的任务清单组织成一个合理的工作计划。通过在 DFS 树中记录节点的结束时间,然后按照这个结束时间进行排序,即可完成图的拓扑排序。