文章目錄
參考視頻:數據結構與算法基礎–第11周09–6.6圖的應用9–6.6.3拓撲排序
一,有向無環圖
1.1 什麼是有向無環圖
有向無環圖:無環的有向圖,簡稱:DAG圖(Directed Acycline Graph)
1.2 有向無環圖的應用
- 有向無環圖常用來描述一個工程或系統的進行過程。(通常把計劃、施工、生產、程序流程等當成是一個工程)
- 一個工程可以分爲若干個子工程,只要完成了這些子工程(活動),就可以導致整個工程的完成。
1.3 如何表示子工程(活動)
AOV 網(拓撲排序)
- 用一個有向圖表示一個工程的各子工程及其相互制約的關係,其中以頂點表示活動,弧表示活動之間的優先制約關係,稱這種有向圖爲頂點表示活動的網,簡稱 AOV網(Activity On Vertex network)。
AOE 網(關鍵路徑)
- 用一個有向圖表示一個工程的各子工程及其相互制約的關係,以弧(邊)表示活動,以頂點表示活動的開始或結束事件,稱這種有向圖爲邊表示活動的網,簡稱爲 AOE網(Activity On Edge)。
二,拓撲排序
拓撲排序引例:排課表
- 使用定點來表示課程
- 可以直觀的表現出該課程有哪些先修課程
2.1 AOV 網的特點
- 若從 i 到 j 有一條有向路徑,則 i 是 j 的前驅;j 是 i 的後繼。
- 若 < i, j > 是網中有向邊,則 i 是 j 的直接前驅;j 是 i 的直接後繼。
- AOV 網中不允許有迴路,因爲如果有迴路存在,則表明某項活動以自己爲先決條件,顯然這是不合理的。
2.2 拓撲排序
2.2.1 定義與方法
定義
- 在 AOV網沒有迴路的前提下,我們將全部活動排列成一個線性序列,使得若 AOV網中有弧 < i, j > 存在,則在這個序列中,i 一定排在 j 的前邊,具有這種性質的線性序列稱爲拓撲有序序列,相應的拓撲有序排序的算法稱爲拓撲排序。
拓撲排序的方法
- 在有向圖中選一個沒有前驅的頂點;
- 從圖中刪除該頂點和所有以它爲尾的弧 ;
- 重複上述兩步,直至全部頂點均已輸出;或者當圖中不存在無前驅的定點爲止。
因爲每次選擇無前驅頂點時都是隨機的,所以可能會出現排序結果不同的情況,如下所示。
2.2.2 檢測 AOV網中是否存在迴路
檢測AOV網中是否存在環的方法:
- 對有向圖構造其頂點的拓撲有序序列,若網中所有的頂點都在它的拓撲有序序列中,則該 AOV網必定不存在環。
- 例如下圖,c3、c6、c8 互爲前驅和後繼,不可能在拓撲排序中被選中和刪除,最終會被留下。
三,Python實現拓撲排序
from collections import defaultdict
class Graph:
def __init__(self,vertices):
self.graph = defaultdict(list)
self.V = vertices
def addEdge(self,u,v):
self.graph[u].append(v)
def topologicalSortUtil(self,v,visited,stack):
visited[v] = True
for i in self.graph[v]:
if visited[i] == False:
self.topologicalSortUtil(i,visited,stack)
stack.insert(0,v)
def topologicalSort(self):
visited = [False]*self.V
stack =[]
for i in range(self.V):
if visited[i] == False:
self.topologicalSortUtil(i,visited,stack)
print (stack)
g= Graph(6)
g.addEdge(5, 2);
g.addEdge(5, 0);
g.addEdge(4, 0);
g.addEdge(4, 1);
g.addEdge(2, 3);
g.addEdge(3, 1);
print ("拓撲排序結果:")
g.topologicalSort()
>>>拓撲排序結果:[5, 4, 2, 3, 1, 0]