【发布时间】:2022-04-08 12:15:23
【问题描述】:
从here 中提取,我们得到了一个最小的迭代 dfs 例程,我称它为最小,因为您几乎无法进一步简化代码:
def iterative_dfs(graph, start, path=[]):
q = [start]
while q:
v = q.pop(0)
if v not in path:
path = path + [v]
q = graph[v] + q
return path
graph = {
'a': ['b', 'c'],
'b': ['d'],
'c': ['d'],
'd': ['e'],
'e': []
}
print(iterative_dfs(graph, 'a'))
这是我的问题,您如何将这个例程转换为拓扑排序方法,其中例程也变得“最小”?我看过这个video,这个想法非常聪明,所以我想知道是否可以将相同的技巧应用到上面的代码中,这样topological_sort 的最终结果也变得“最小”。
不要求拓扑排序的版本不是对上述例程的微小修改,我已经见过其中的几个。问题不是“我如何在 python 中实现拓扑排序”,而是找到上述代码的最小可能调整集以成为topological_sort。
补充意见
作者在原文中说:
不久前,我读到 Guido van Rossen 的一个图形实现 看似简单。现在,我坚持纯python最小系统 以最少的复杂性。这个想法是能够探索 算法。稍后,您可以细化和优化代码,但您将 可能想在编译语言中执行此操作。
这个问题的目标不是优化iterative_dfs,而是想出一个从它派生的最小版本的拓扑排序(只是为了了解更多关于图论算法的信息)。事实上,我想一个更普遍的问题可能是给定一组最小算法,{iterative_dfs,recursive_dfs,iterative_bfs,recursive_dfs},它们的拓扑排序推导是什么?虽然这会使问题变得更冗长/复杂,但从 iterative_dfs 中找出 topological_sort 就足够了。
【问题讨论】:
-
@TomKarzes 现在理解你的意思,这完全有道理,好主意!您是否认为在遍历之前预处理将 deps 列表转换为集合的图形过于“昂贵”,因此您不需要将两个结构都保留在图形中。假设应用程序要处理的图形类型可能是 {graph_many_nodes}x{all_nodes_have_many_deps, few_nodes_many_deps} 之类的笛卡尔积,因此值得优化。无论如何,问题更多的是关于最少的代码(尽可能简单),因此在这种情况下,解决方案是否快速无关紧要。
-
还有
path=[]...只是不要这样做... -
@user3012759 你的意思是把它作为一个局部变量而不是一个参数?看看我在帖子中的原始article,如果你仔细想想,作者选择
path=[]作为参数的原因是这样迭代和递归版本的接口都可以是同样,如果您将其作为本地 var,您将在这一点上失败。 -
@BPL - 在这种情况下,它确实按预期工作,但这只是因为另一个技术性。
path = ...的行将新列表分配给本地 var 路径并返回,但如果将来有人进入并更改为path.append(v)执行“同样的事情”,你会突然得到path保持调用之间的值 - 通常你不想将可变变量作为默认参数放在 python 中 -
@ShihabShahriar 我明白你为什么要问......老实说,我在决定接受哪个答案时遇到了很多困难,它们都非常适合我。我之所以接受 Blckknght 主要是因为点赞的数量,它是第一个发布的,它对公众更有用,因为它提供了非常好的见解。另一方面,如果我们严格坚持我提出的问题,我认为您的答案更合适的 ...所以...我不知道,也许我选错了两个答案真的很好,但我需要选择一个....
标签: python algorithm graph-theory depth-first-search topological-sort