[英]Topological Sort Algorithm (DFS) Implementation in Python
我是 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
当我尝试构建拓扑排序算法时,我创建了一个新的 function,它主要检查要添加到排序列表中的节点的“可用性”(即:是否已访问其相邻节点)
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 进行拓扑排序。
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
class Graph:
def __init__(self):
self.edges = {}
def addNode(self, node):
self.edges[node] = []
def addEdge(self, node1, node2):
self.edges[node1] += [node2]
def getSub(self, node):
return self.edges[node]
def DFSrecu(self, start, path):
for node in self.getSub(start):
if node not in path:
path = self.DFSrecu(node, path)
if start not in path:
path += [start]
return path
def topological_sort(self, start):
topo_ordering_list = self.DFSrecu(start, [])
# this for loop it will help you to visit all nodes in the graph if you chose arbitrary node
# because you need to check if all nodes in the graph is visited and sort them
for node in g.edges:
if node not in topo_ordering_list:
topo_ordering_list = g.DFSrecu(node, topo_ordering_list)
return topo_ordering_list
if __name__ == "__main__":
g = Graph()
for node in ['S', 'B', 'A', 'C', 'G', 'I', "L", 'D', 'H']:
g.addNode(node)
g.addEdge("S", "A")
g.addEdge("S", "B")
g.addEdge("B", "D")
g.addEdge("D", "H")
g.addEdge("D", "G")
g.addEdge("H", "I")
g.addEdge("I", "L")
g.addEdge("G", "I")
last_path1 = g.topological_sort("D")
last_path2 = g.topological_sort("S")
print("Start From D: ",last_path1)
print("start From S: ",last_path2)
Output:
从 D 开始:['L', 'I', 'H', 'G', 'D', 'A', 'B', 'S', 'C']
从 S 开始:['A', 'L', 'I', 'H', 'G', 'D', 'B', 'S', 'C']
你可以在这里看到 'C' 包含在拓扑排序列表中,即使它没有连接到任何其他节点但图中的 'C' 并且你需要访问她这就是你需要在 topological_sort() function 中循环的方式
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.