本篇文章给大家带来的内容是关于python实现有向无环图的拓扑排序代码示例,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
python有向无环图的拓扑排序
拓扑排序的官方定义为:由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。而个人认为,拓扑排序即是在图的基本遍历法上引入了入度的概念并围绕入度来实现的排序方法,拓扑排序与python多继承中mro规则的排序类似,若想深入研究mro规则的c3算法,不妨了解一下 dag(有向无环图) 的拓扑排序。
入度:指有向图中某节点被指向数目之和
有向无环图:directed acyclic graph,简称dag,若熟悉机器学习则肯定对dag不陌生,如ann、dnn、cnn等则都是典型的dag模型,对这类模型此处不再过多敷述,有兴趣的可以自行学习。
以一个有向无环图为例,如下图:
# 定义图结构graph = { "a": ["b","c"], "b": ["d","e"], "c": ["d","e"], "d": ["f"], "e": ["f"], "f": [],}
如图
a的指向的元素为b、c
b的指向的元素为d、e
c的指向的元素为d、e
d的指向的元素为f
e的指向的元素为f
f的指向的元素为空
即a的入度为0,b的入度为1,c的入度为1,d的入度为2,e的入度为2,f的入度为2
在dag的拓扑排序中,每次都选取入度为 0 的点加入拓扑队列中,再删除与这一点连接的所有边。
首先找到入度为0的点a,把a从队列中取出,同时添加到结果中并把a相关的指向移除,即b、c的入度减少1变为0并将b,c添加到队列中,再从队列首部取出入度为0的节点,以此类推,最后输出结果,完成dag的拓扑排序。
def topologicalsort(g): # 创建入度字典 in_degrees = dict((u, 0) for u in g) # 获取每个节点的入度 for u in g: for v in g[u]: in_degrees[v] += 1 # 使用列表作为队列并将入度为0的添加到队列中 q = [u for u in g if in_degrees[u] == 0] res = [] # 当队列中有元素时执行 while q: # 从队列首部取出元素 u = q.pop() # 将取出的元素存入结果中 res.append(u) # 移除与取出元素相关的指向,即将所有与取出元素相关的元素的入度减少1 for v in g[u]: in_degrees[v] -= 1 # 若被移除指向的元素入度为0,则添加到队列中 if in_degrees[v] == 0: q.append(v) return resprint(topologicalsort(graph))
输出结果:
['a', 'c', 'b', 'e', 'd', 'f']
代码输出结果与上述分析相符
以上就是python实现有向无环图的拓扑排序代码示例的详细内容。