日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

数据结构之图:有向图的拓扑排序,Python代码实现——26

發布時間:2024/7/5 python 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构之图:有向图的拓扑排序,Python代码实现——26 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

有向圖的拓撲排序

拓撲排序介紹

什么是拓撲排序?

  • 一個有向圖的拓撲排序(Topological sort 或 Topological ordering)是根據其有向邊從頂點U到頂點V對其所有頂點的一個線性排序
  • 舉個例子:讓一個拓撲排序的圖中的所有頂點代表某項要執行的任務組合,那么它的邊就可以代表要執行要執行其中某一項任務必須要先先于另外一項任務的限制條件,在這個例子中,拓撲排序就是這項任務組合的有效排序

有向圖中的環

知道了拓撲排序可以用來解決優先級問題后,還要確保要解決排序問題的圖中沒有環:

  • 如果學習x課程前必須先學習y課程,學習y課程前必須先學習z課程,學習z課程前必須先學習x課程,那么一定是有問題了, 我們就沒有辦法學習了,因為這三個條件沒有辦法同時滿足。其實這三門課程x、y、z的條件組成了一個環:

如何檢測有向圖中的環

借助一個列表ontrack,其索引代表圖中的頂點

  • 在如果當前頂點正在搜索,則把對應的ontrack數組中的值改為True;
  • 如果當前頂點搜索完畢,則把對應的ontrack數組中的值改為False;
  • 如果即將要搜索某個頂點,但該頂點在當前搜索時標識為True,則圖中有環;
  • 基于DFS使用Python代碼實現拓撲排序

    檢測圖中的環

    檢測的目標,對應的實現了這張圖的類方法:點擊回到上一節查看代碼

    主要屬性和方法

  • 構造方法__init__()中
    graph為需要進行拓撲排序的圖;marked標記當前節點是否已經搜索完畢;has_cycle用于標記當前圖中是否存在環;ontrack標記當次所處搜索中頂點是否已經遍歷過
  • dfs() 使用DFS算法對圖進行遍歷,判斷圖中是否存在環
  • 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實現圖中頂點的拓撲排序

    主要屬性方法設計
  • 相比于之前的圖新增了一個stack,stack是一個列表(看做棧),按順序記錄拓撲排序所走過的頂點
  • dfs() 使用DFS算法對頂點進行拓撲排序并將結果儲存到stack列表中
  • sort_vertices() 返回排序后的頂點
  • 排序步驟






    點擊查看圖對應的類方法

    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的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。