Python中的拓扑排序算法(DFS)实现

Posted

技术标签:

【中文标题】Python中的拓扑排序算法(DFS)实现【英文标题】:Topological Sort Algorithm (DFS) Implementation in Python 【发布时间】:2020-10-26 13:37:42 【问题描述】:

我是 python 和算法的新手。我一直在尝试实现拓扑排序算法一段时间,但似乎无法创建一个有效的结构。我制作的函数在 adj 列表中表示的图形上运行。

当我有一个 DFS 时,会自上而下地发现节点,并且已经访问过且未再次处理的节点:

def DFS(location, graph, visited = None): 
  if visited == None: 
      visited = [False for i in range(len(graph))]
  if visited[location] == True:
      return
    
  visited[location] = True
  node_visited.append(location)

  for node in graph[location]:
      DFS(node, graph, visited)
  return visited

当我尝试构建拓扑排序算法时,我创建了一个新函数,该函数主要检查要添加到排序列表中的那个节点的“可用性”(即:它的相邻节点是否已经被访问过)

def availability(graph, node):
    count = 0
    for neighbour in graph[node]:
        if neighbour in available_nodes:
            count += 1
    if count != 0:
        return False
    return True

但是,我的问题是,一旦我访问了节点路径以到达图表底部,DFS 就不允许我重新访问这些节点。因此,一旦我发现路径的尽头,我所做的任何更新都无法处理。

我的方法可能完全不正确,但我想知道是否有人可以帮助改进我的实现设计,或者解释实现通常是如何完成的。提前致谢。

【问题讨论】:

你不能像你那样使用简单的 DFS 进行拓扑排序(你需要一种更微妙的方式来查看你的节点是否被访问过)。我建议你看看this wikipedia page 上描述的算法并实现其中一个。 【参考方案1】:

您不需要可用性检查来使用 DFS 进行拓扑排序。

DFS 本​​身确保在其子节点已被处理之前您不会离开节点,因此如果您在 DFS 完成时将每个节点添加到列表中,它们将以(反向)拓扑顺序添加。

不过,不要忘记绘制整个图表,如下所示:

def toposort(graph):
    visited = [False for i in range(len(graph))]
    result = []

    def DFS(node):
        if visited[node]:
            return
        visited[node] = True
        for adj in graph[node]:
              DFS(adj)
        result.append(node)
    
    for i in range(len(graph)):
        DFS(i)

    return result

【讨论】:

以上是关于Python中的拓扑排序算法(DFS)实现的主要内容,如果未能解决你的问题,请参考以下文章

逆拓扑排序实现思想以及通过DFS算法实现逆拓扑排序(C语言)

拓扑排序的原理及其实现

使用 DFS 算法对有向图和无向图进行拓扑排序

[数据结构]Graph之拓扑排序BFS&DFS实现

挑战程序设计竞赛(算法和数据结构)——15.2拓扑排序(dfs,bfs)的JAVA实现

拓扑排序