7.5 拓撲排序及關鍵路徑
阿新 • • 發佈:2020-08-14
title: 資料結構 | 圖-5 | 拓撲排序
date: 2019-11-27 17:14:58
tags: 資料結構
拓撲排序、關鍵路徑
拓撲排序
背景
- 頂點——表示課程
- 有向弧——表示先決條件,若課程i是課程j的先決條件,則圖中有弧<i,j>
- 拓撲排序
學生應按怎樣的順序學習這些課程,才能無矛盾、順利地完成學業
定義
AOV網
用頂點表示活動,用弧表示活動間優先關係的有向圖稱為頂點表示活動的網(Activity On Vertex network),簡稱AOV網。
若<vi,vj>是圖中有向邊,則vi是vj的直接前驅,vj是vi的直接後繼;
AOV網中不允許有迴路,這意味著某項活動以自己為先決條件;
拓撲排序的定義
把AOV網路中各頂點按照它們相互之間的優先關係排列成一個線性序列的過程叫拓撲排序
-拓撲排序應用
檢測AOV網中是否存在環:
對有向圖構造其頂點的拓撲有序序列,若網中所有頂點都在它的拓撲序列,則該AOV網必定無環
方法
- 在有向圖中選一個沒有前驅的頂點且輸出之;
- 從圖中刪除該頂點和所有以它為尾的弧;
- 重複上述兩步,直至全部頂點均已輸出,或圖中不存在無前驅的頂點。
演算法實現
以鄰接表作儲存結構,
- 把鄰接表中所有入度為0的頂點進棧;
- 棧非空時,輸出棧頂元素Vj並退棧;
- 在鄰接表中查詢Vj的直接後繼Vk,把Vk的入度減1;若Vk的入度為0則進棧;
- 重複上述操作直至棧空為止。
若棧空時輸出的頂點個數不是n,則有向圖有環;否則,拓撲排序完畢
Status TopologicalSort(ALGraph G) { for(i = 0;i <G.vexnum; ++ i ) //查詢入度為為零的頂點 if(! Indegree[i]) //把入度為零的頂點進棧 push (S,i ); count = 0; //計數器置0 while (! StackEmpty(s)) { pop(s, i); printf(i,Gvextices[i].data); ++count;//輸出頂點、計數 for(p=G.vextices[i].firstarc; p ; p = p->nextarc) { k = p->adjvex; //得到與輸出頂點相鄰接的頂點下標 if(! (--indegree[k])) push( S,k); //將鄰接點的入度減1,將為零的入棧 }//for }//while if (count<G.vexnum) return ERROR;//該圖有迴路 else return OK; }//TopologicalSort
關鍵路徑
背景
- 把工程計劃表示為有向圖,用頂點表示事件,弧表示活動;
每個事件表示在它之前的活動已完成,在它之後的活動可以開始;
事件 V1——表示整個工程開始
事件 V9——表示整個工程結束
其中,T為所有以第j個頂點為頭的弧的集合。
定義
AOE網(Activity On Edge)
邊表示活動的網。AOE網是一個帶權的有向無環圖,其中頂點表示事件,弧表示活動,權表示活動持續時間
路徑長度
路徑上各活動持續時間之和。
關鍵路徑
路徑長度最長的路徑叫關鍵路徑。
Ve——事件Vj的最早發生時間Ve(j)
- 源點的最早發生時間為0,其餘任一頂點Vj的最早發生時間,等於從源點出發沿著各條路徑達到Vj時每條路徑上權的累加和的最大值。計算公式為:
Ve(j)=Max{ve(i) + dut(<i ,j>)}
<i,j>∈T, j = 1,2,3…n-1
Vl—事件的最遲發生時間Vl(j)
- 匯點的最遲發生時間Vl[n]等於匯點的最早發生時間Ve[n]。
其餘任一頂點Vi的最遲發生時間等於從匯點的最遲發生時間中減去從頂點Vi出發沿著各條路徑達到匯點時,每條路徑上權的累加和的最大值。
最遲發生時間一般用下列公式計算:
Vl(i)=Min{vl(j)-dut(<i ,j>)}
<i,j> ∈S, i = n -2,..,0
其中, S為所有以第i個頂點為尾的弧的集合。
e(i)——表示活動ai的最早開始時間
l(i)——表示活動ai的最遲開始時間
設活動ai用弧<j,k>表示,
其持續時間記為:dut(<j,k>)
則有:(1)e(i)=Ve(j) //最早開始時間是弧尾事件的最早發生時間
(2)l(i)=Vl(k)-dut(<j,k>)//最遲開始時間是弧頭事件的最晚發生時間減去活動的持續時間,即弧的權值
- l(i)-e(i)——表示完成活動ai的時間餘量
- 關鍵活動——關鍵路徑上的活動叫關鍵活動,即l(i)=e(i)的活動
演算法實現
描述
- 輸入頂點和弧資訊,建立其鄰接表
- 計算每個頂點的入度
- 對其進行拓撲排序
- 排序過程中求頂點的Ve[i]
- 將得到的拓撲序列進棧
- 按逆拓撲序列求頂點的Vl[i]
- 計算每條弧的e[i]和l[i],找出e[i]=l[i]的關鍵活動
……沒看,待更新