数据结构之图:有向图的拓扑排序,Python代码实现——26
生活随笔
收集整理的這篇文章主要介紹了
数据结构之图:有向图的拓扑排序,Python代码实现——26
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
有向圖的拓撲排序
拓撲排序介紹
什么是拓撲排序?
- 一個有向圖的拓撲排序(Topological sort 或 Topological ordering)是根據其有向邊從頂點U到頂點V對其所有頂點的一個線性排序
- 舉個例子:讓一個拓撲排序的圖中的所有頂點代表某項要執行的任務組合,那么它的邊就可以代表要執行要執行其中某一項任務必須要先先于另外一項任務的限制條件,在這個例子中,拓撲排序就是這項任務組合的有效排序
有向圖中的環
知道了拓撲排序可以用來解決優先級問題后,還要確保要解決排序問題的圖中沒有環:
- 如果學習x課程前必須先學習y課程,學習y課程前必須先學習z課程,學習z課程前必須先學習x課程,那么一定是有問題了, 我們就沒有辦法學習了,因為這三個條件沒有辦法同時滿足。其實這三門課程x、y、z的條件組成了一個環:
如何檢測有向圖中的環
借助一個列表ontrack,其索引代表圖中的頂點
基于DFS使用Python代碼實現拓撲排序
檢測圖中的環
檢測的目標,對應的實現了這張圖的類方法:點擊回到上一節查看代碼
主要屬性和方法
graph為需要進行拓撲排序的圖;marked標記當前節點是否已經搜索完畢;has_cycle用于標記當前圖中是否存在環;ontrack標記當次所處搜索中頂點是否已經遍歷過
Python代碼實現
class DirectedCycle:def __init__(self, graph):self.graph = graphself.marked = [False for _ in range(self.graph.num_vertices)]self.has_cycle = Falseself.ontrack = [False for _ in range(self.graph.num_vertices)]def dfs(self):"""We need to search every vertex of this graph"""def dfs(index):self.marked[index] = Trueself.ontrack[index] = Truefor vertex in self.graph.adj_list[index]:if not self.ontrack[vertex]:dfs(vertex)if self.ontrack[vertex]:self.has_cycle = Truereturnself.ontrack[index] = Falsefor i in range(self.graph.num_vertices):if not self.marked[i]:dfs(i)if __name__ == '__main__':graph = Digraph(5)graph.point_edge(3, 0)graph.point_edge(0, 2)graph.point_edge(2, 1)graph.point_edge(1, 0)graph.point_edge(1, 4)DC = DirectedCycle(graph)print(DC.has_cycle)DC.dfs()print(DC.has_cycle)運行結果
False True使用DFS實現圖中頂點的拓撲排序
主要屬性方法設計
排序步驟
點擊查看圖對應的類方法
Python代碼實現
class DepthFirstOrder:def __init__(self, graph):self.graph = graphself.marked = [False for _ in range(self.graph.num_vertices)]self.stack = []def dfs(self):"""Search each vertex and rank its order"""def dfs(index):self.marked[index] = Truefor x in self.graph.adj_list[index]:if not self.marked[x]:dfs(x)self.stack.insert(0, index)for i in range(self.graph.num_vertices):# for i in [5, 4, 3, 2, 1, 0]:if not self.marked[i]:dfs(i)return self.stackdef sort_vertices(self):return self.dfs()if __name__ == '__main__':graph = Digraph(6)# graph.point_edge(0, 3)graph.point_edge(0, 2)graph.point_edge(0, 3)graph.point_edge(2, 4)graph.point_edge(3, 4)graph.point_edge(4, 5)graph.point_edge(1, 3)print(graph.adj_list)DF = DepthFirstOrder(graph)print(DF.sort_vertices())運行結果:
[[2, 3], [3], [4], [4], [5], []] [1, 0, 3, 2, 4, 5]排序結果會受到對頂點遍歷的順序影響,但是最終結果一定會是一條有效的符合邏輯的排序
檢測一張圖是否有環,并進行拓撲排序
調用前面所實現的方法即可,點擊查看代碼中使用到的圖對應的類方法
from Structure.graph.digraph import Digraph from Structure.graph.DepthFirstOrder import DepthFirstOrder from Structure.graph.DirectedCycle import DirectedCycleclass TopoLogical:def __init__(self, graph):self.order = Noneself.cycle = DirectedCycle(graph)if not self.cycle.has_cycle:DFO = DepthFirstOrder(graph)self.order = DFO.sort_vertices()def has_cycle(self):# return self.cycle.has_cyclereturn not self.orderdef stack(self):return self.orderif __name__ == '__main__':graph = Digraph(6)graph.point_edge(0, 2)graph.point_edge(0, 3)graph.point_edge(2, 4)graph.point_edge(3, 4)graph.point_edge(4, 5)graph.point_edge(1, 3)print(graph.adj_list)TL = TopoLogical(graph)print(TL.has_cycle())print(TL.stack())運行結果
[[2, 3], [3], [4], [4], [5], []] False [1, 0, 3, 2, 4, 5]總結
以上是生活随笔為你收集整理的数据结构之图:有向图的拓扑排序,Python代码实现——26的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 回溯算法背包问题迭代c语言,回溯法解决0
- 下一篇: python 存储图片 alpha_保存