拓扑排序(Topological sorting)

9 篇文章 0 订阅
7 篇文章 0 订阅

简介

拓扑排序(Topological sorting)也是leetcode中的一类常见题型;他对于dependency任务做一个先后的排序,还是挺重要的。第一是build任务中我们需要这样的排序使得软件可以逐步build;另外我接触这个的时候是关于neural network compile的,在compile的过程中,哪个op可以先计算,哪个op需要等待,实际上也是用topological sorting。

伪代码

L ← Empty list that will contain the sorted elements
S ← Set of all nodes with no incoming edge

while S is not empty do
    remove a node n from S
    add n to L
    for each node m with an edge e from n to m do
        remove edge e from the graph
        if m has no other incoming edges then
            insert m into S

if graph has edges then
    return error   (graph has at least one cycle)
else 
    return L   (a topologically sorted order)

在这个伪代码中,S负责储存所有没有任何dependency的可执行任务。在把每个S node拿出来的过程中,我们假定S node已经被处理,来计算剩下的zero dependency node, 以此类推。如果最后发现还有剩余的edge(或者node), 那么就说明不存在topological sorting,也就是说graph有cycle。否则依次取出的S node就构成了topological sorting。

Python implementation 

我们就以这道题举例:

L: list就好,毕竟只需要append。

S: 又需要append又需要popleft, 还是用deque吧

另外我们注意需要在for loop时迅速获得所有neighbor, 另外也需要remove edge。本质上我觉得是说需要两个map, 一个是source to target map以便获得所有的neighbor;一个是target to source map, 可以方便remove来检查是否所有的source都已被执行。最后附上这个问题我的python解答:

from collections import defaultdict, deque

class Solution:
    def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        source_target = defaultdict(set)
        target_source = defaultdict(set)
        for target, source in prerequisites:
            source_target[source].add(target)
            target_source[target].add(source)
        
        empty = deque([i for i in range(numCourses) if i not in target_source])
        topo_list = []
        while empty:
            source = empty.popleft()
            topo_list.append(source)
            for c_target in source_target[source]:
                target_source[c_target].remove(source)
                if len(target_source[c_target]) == 0:
                    empty.append(c_target)
        
        if len(topo_list) == numCourses:
            return topo_list
        return []

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值