No.4有向无环图的拓扑排序

1.什么是有向无环图(简称DAG)呢?
举个浅显易懂的有向无环图拓扑排序的例子(Linux驱动匹配):

  • 比如现在有abcde五个驱动模块文件,它们的具体的依赖顺序未知
  • 但是给出了单个驱动模块文件会依赖其它的驱动依赖模块
    1> a->bce,表示a的正常工作会依赖bce这三个驱动模块,但是bce之间的依 赖顺序又是未知的
    2> b->d,b依赖d
    3> c->d,c依赖d
    4> e->cd,e的正常工作会依赖cd两个驱动模块,但cd之间的顺序未知
    5> d->,d不依赖任何一个模块
  • 现在我们要解出abcde五个驱动模块文件的争取依赖顺序,例如是a->b->c->d->e,还是a->e->c->d->b,还是都不是,我们该如何求解呢?那么有向无环图的拓扑排序就可以帮我们解决这个问题

2 .在1中的例子的正确答案我们可以用一个图来表示,即有向无环图,如下:
在这里插入图片描述

  • 这个图比较简单我们可以一眼看出它的拓扑排序顺序为:aecbd(也就是我们1中的正确答案),但是我们要用代码算出结果来才行,遇到复杂的图一眼是看不出来的。

  • 那么DAG的正确算法步骤是什么呢有两种,这里我们用的是入度表来实现的,基本步骤如下
    1>找出图中0入度的顶点(入读为0也就是说圈上没有箭头指向它).
    2>依次在图中删除这些顶点,删除后再找出0入度的顶点.
    3>然后再删除……再找出…… .
    4>直至删除所有顶点,即完成拓扑排序.
    5>将删除的顶点依次从左到右放
    删掉第一个入度为0的点为A之后的顺序为:a,图更新为如下:
    在这里插入图片描述
    删掉第二个入度为0的点为e之后的顺序为:a->e,图更新为如下:
    在这里插入图片描述
    删掉第三个入度为0的点为c之后的顺序为:a->e->c,图更新为如下
    在这里插入图片描述
    删掉第四个入度为0的点为b之后的顺序为:a->e->c->b,图更新为如下
    在这里插入图片描述
    最后删除掉d,最后拓扑排序的顺序为:a->e->c->b->d

3 .下面我们用python代码来实现以上的过程所得到的结果

  • 将1中的依赖用字典表示为G = {‘a’: ‘bce’, ‘b’: ‘d’, ‘c’: ‘d’, ‘d’: ‘’, ‘e’: ‘cd’}
  • python具体实现如下
def directed_acyclic_graph_topology_sort(graph):
   in_degrees = dict((u, 0) for u in graph)  # 初始化所有顶点入度为0
   vertex_num = len(in_degrees)
   for u in graph:
       for v in graph[u]:
           in_degrees[v] += 1  # 计算每个顶点的入度
   Q = [u for u in in_degrees if in_degrees[u] == 0]  # 筛选入度为0的顶点
   Seq = []
   while Q:
       u = Q.pop()  # 默认从最后一个删除
       Seq.append(u)
       for v in graph[u]:
           in_degrees[v] -= 1  # 移除其所有指向
           if in_degrees[v] == 0:
               Q.append(v)  # 再次筛选入度为0的顶点
   if len(Seq) == vertex_num:  # 如果循环结束后存在非0入度的顶点说明图中有环,不存在拓扑排序
       return Seq
   else:
       print("there's a circle.")


G = {'a': 'bce', 'b': 'd', 'c': 'd', 'd': '', 'e': 'cd'}
print(directed_acyclic_graph_topology_sort(G))
['a', 'e', 'c', 'b', 'd']
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值