拓扑排序,递归,使用生成器
时间:2020-03-06 14:29:16 来源:igfitidea点击:
数据:依赖项列表,已被验证为非循环。所以在这里," a"取决于" b"," c"(c取决于d),等等。
A = { 'a' : dict(b=1, c=1),
'c' : dict(d=1),
'd' : dict(e=1,f=1,g=1),
'h' : dict(j=1)
}
我想有一个自上而下的递归解决方案,可以说找到从
'a':a,c,d,e,g,f,b
因此,现在(非发电机解决方案):
def get_all(D,k):
L = []
def get2(D,k):
L.append(k)
for ii in D.get(k,[]):
get2(D, ii)
get2(D,k)
return L
显然,这是非常薄弱的:)我一直在想如何在其中获得收益,我想感谢所有py-foo你们都可以带来的收益。
解决方案
试试这个:
#!/usr/bin/env python
def get_all(D, k):
yield k
for ii in D.get(k, []):
for jj in get_all(D, ii):
yield jj
A = { 'a' : dict(b=1, c=1),
'c' : dict(d=1),
'd' : dict(e=1,f=1,g=1),
'h' : dict(j=1)
}
for ii in get_all(A,'a'):
print ii
给我
steve@rei:~/code/tmp $ python recur.py a c d e g f b
这两个答案都给出相同的结果,但是如果我们从'b'中添加对'c'的依赖关系(这不会引入循环,则如果我对问题的理解是正确的,则对给定图的简单更改给出错误的答案)该图是有向的),输出为:
一种
C
d
Ë
G
F
b
d
Ë
G
F
`
这不是完全有帮助。试试这个小的变化,它可以跟踪图形中的哪些节点已经被访问过:
def get_all(D, k, seen=None):
if not seen:
seen = set( )
if k not in seen:
seen.add(k)
yield k
for ii in D.get(k, []):
for jj in get_all(D, ii, seen):
yield jj

