拓扑排序问题

拓扑排序:

几乎在所有的项目中,待完成的任务之间通常都会存在着某些依赖关系,这些关系会对它们的执行顺序形成部分约束。

对于这种依赖关系,我们通常很容易将其表示成一个有向无环路图(DAG),并将寻找其中依赖顺序的过程(寻找所有沿着特定顺序前进的边与点)成为拓扑排序(topological sorting)


解决思路:

如何归简?

首先移除其中一个节点,然后解决其余n-1个节点的问题。但,这首先要保证移除之后还是一个DAG。就是移除哪些没有入边的节点。

而清单4-9中的程序naive_topsort每次移除的都是任意的节点,这并不能保证剩余的节点还是一个DAG。清单4-10满足这样的条件,用count计数,记录每个结点的指向自己的节点个数{'a': 0, 'b': 1, 'c': 1, 'd': 2, 'e': 1, 'f': 4}

然后逐个移除count中计数为0的节点。

代码:

def naive_topsort(G, S=None):
    if S is None: S = set(G) # Default: All nodes
    print(S)
    if len(S) == 1: return list(S) # Base case, single node
    v = S.pop() # Reduction: Remove a node
    seq = naive_topsort(G, S) # Recursion (assumption), n-1
    min_i = 0
    print("seq"," ",seq)
    for i, u in enumerate(seq):
        if v in G[u]: min_i = i+1 # After all dependencies
    print(min_i,' ',v)
    seq.insert(min_i, v)
    print(seq)
    return seq

def topsort(G):
    count = dict((u, 0) for u in G) # The in-degree for each node
    for u in G:
        for v in G[u]:
            count[v] += 1 # Count every in-edge
    print(count)
    Q = [u for u in G if count[u] == 0] # Valid initial nodes
    S = [] # The result
    while Q: # While we have start nodes...
        u = Q.pop() # Pick one
        S.append(u) # Use it as first of the rest
        for v in G[u]:
            count[v] -= 1 # "Uncount" its out-edges
            if count[v] == 0: # New valid start nodes?
                Q.append(v) # Deal with them next
    return S

if __name__=="__main__":
    G={
        'a':set('bf'),
        'b':set('cdf'),
        'c':set('d'),
        'd':set('ef'),
        'e':set('f'),
        'f':set('')   
        }
    seq=naive_topsort(G)
    print(seq)
    seq2=topsort(G)
    print(seq2)

运行结果:

{'d', 'e', 'c', 'f', 'a', 'b'}
{'e', 'c', 'f', 'a', 'b'}
{'c', 'f', 'a', 'b'}
{'f', 'a', 'b'}
{'a', 'b'}
{'b'}
seq   ['b']
0   a
['a', 'b']
seq   ['a', 'b']
2   f
['a', 'b', 'f']
seq   ['a', 'b', 'f']
2   c
['a', 'b', 'c', 'f']
seq   ['a', 'b', 'c', 'f']
0   e
['e', 'a', 'b', 'c', 'f']
seq   ['e', 'a', 'b', 'c', 'f']
4   d
['e', 'a', 'b', 'c', 'd', 'f']
['e', 'a', 'b', 'c', 'd', 'f']
{'a': 0, 'b': 1, 'c': 1, 'd': 2, 'e': 1, 'f': 4}
['a', 'b', 'c', 'd', 'e', 'f']

由程序得出,《Python算法教程》中的清单4-9naive_topsort并不能总是得到正确的拓扑排序的结果。

清单4-10topsort是可以得到正确结果的。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值