拓扑排序,递归,使用生成器
时间: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