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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

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

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

有向圖的拓?fù)渑判?/h1>

拓?fù)渑判蚪榻B

什么是拓?fù)渑判?#xff1f;

  • 一個(gè)有向圖的拓?fù)渑判?#xff08;Topological sort 或 Topological ordering)是根據(jù)其有向邊從頂點(diǎn)U到頂點(diǎn)V對(duì)其所有頂點(diǎn)的一個(gè)線性排序
  • 舉個(gè)例子:讓一個(gè)拓?fù)渑判虻膱D中的所有頂點(diǎn)代表某項(xiàng)要執(zhí)行的任務(wù)組合,那么它的邊就可以代表要執(zhí)行要執(zhí)行其中某一項(xiàng)任務(wù)必須要先先于另外一項(xiàng)任務(wù)的限制條件,在這個(gè)例子中,拓?fù)渑判蚓褪沁@項(xiàng)任務(wù)組合的有效排序

有向圖中的環(huán)

知道了拓?fù)渑判蚩梢杂脕?lái)解決優(yōu)先級(jí)問(wèn)題后,還要確保要解決排序問(wèn)題的圖中沒(méi)有環(huán):

  • 如果學(xué)習(xí)x課程前必須先學(xué)習(xí)y課程,學(xué)習(xí)y課程前必須先學(xué)習(xí)z課程,學(xué)習(xí)z課程前必須先學(xué)習(xí)x課程,那么一定是有問(wèn)題了, 我們就沒(méi)有辦法學(xué)習(xí)了,因?yàn)檫@三個(gè)條件沒(méi)有辦法同時(shí)滿足。其實(shí)這三門課程x、y、z的條件組成了一個(gè)環(huán):

如何檢測(cè)有向圖中的環(huán)

借助一個(gè)列表ontrack,其索引代表圖中的頂點(diǎn)

  • 在如果當(dāng)前頂點(diǎn)正在搜索,則把對(duì)應(yīng)的ontrack數(shù)組中的值改為True;
  • 如果當(dāng)前頂點(diǎn)搜索完畢,則把對(duì)應(yīng)的ontrack數(shù)組中的值改為False;
  • 如果即將要搜索某個(gè)頂點(diǎn),但該頂點(diǎn)在當(dāng)前搜索時(shí)標(biāo)識(shí)為True,則圖中有環(huán);
  • 基于DFS使用Python代碼實(shí)現(xiàn)拓?fù)渑判?/h2>

    檢測(cè)圖中的環(huán)

    檢測(cè)的目標(biāo),對(duì)應(yīng)的實(shí)現(xiàn)了這張圖的類方法:點(diǎn)擊回到上一節(jié)查看代碼

    主要屬性和方法

  • 構(gòu)造方法__init__()中
    graph為需要進(jìn)行拓?fù)渑判虻膱D;marked標(biāo)記當(dāng)前節(jié)點(diǎn)是否已經(jīng)搜索完畢;has_cycle用于標(biāo)記當(dāng)前圖中是否存在環(huán);ontrack標(biāo)記當(dāng)次所處搜索中頂點(diǎn)是否已經(jīng)遍歷過(guò)
  • dfs() 使用DFS算法對(duì)圖進(jìn)行遍歷,判斷圖中是否存在環(huán)
  • Python代碼實(shí)現(xiàn)

    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)

    運(yùn)行結(jié)果

    False True

    使用DFS實(shí)現(xiàn)圖中頂點(diǎn)的拓?fù)渑判?/h4>

    主要屬性方法設(shè)計(jì)
  • 相比于之前的圖新增了一個(gè)stack,stack是一個(gè)列表(看做棧),按順序記錄拓?fù)渑判蛩哌^(guò)的頂點(diǎn)
  • dfs() 使用DFS算法對(duì)頂點(diǎn)進(jìn)行拓?fù)渑判虿⒔Y(jié)果儲(chǔ)存到stack列表中
  • sort_vertices() 返回排序后的頂點(diǎn)
  • 排序步驟






    點(diǎn)擊查看圖對(duì)應(yīng)的類方法

    Python代碼實(shí)現(xiàn)

    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())

    運(yùn)行結(jié)果:

    [[2, 3], [3], [4], [4], [5], []] [1, 0, 3, 2, 4, 5]

    排序結(jié)果會(huì)受到對(duì)頂點(diǎn)遍歷的順序影響,但是最終結(jié)果一定會(huì)是一條有效的符合邏輯的排序

    檢測(cè)一張圖是否有環(huán),并進(jìn)行拓?fù)渑判?/h4>

    調(diào)用前面所實(shí)現(xiàn)的方法即可,點(diǎn)擊查看代碼中使用到的圖對(duì)應(yīng)的類方法

    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())

    運(yùn)行結(jié)果

    [[2, 3], [3], [4], [4], [5], []] False [1, 0, 3, 2, 4, 5]

    總結(jié)

    以上是生活随笔為你收集整理的数据结构之图:有向图的拓扑排序,Python代码实现——26的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。