AOE網與關鍵路徑簡介

前面我們說過的拓撲排序主要是為解決一個工程能否順序進行的問題,但有時我們還需要解決工程完成需要的最短時間問題。如果我們要對一個流程圖獲得最短時間,就必須要分析它們的拓撲關系,并且找到當中最關鍵的流程,這個流程的時間就是最短時間。

在前面講了AOV網的基礎上,來介紹一個新的概念。在一個表示工程的帶權有向圖中,用頂點表示事件,用有向邊表示活動,用邊上的權值表示活動的持續時間,這種有向圖的邊表示活動的網,稱之為AOE網(Activity On edge Network)。由于一個工程,總有一個開始,一個結束,在正常情況下,AOE網只有一個源點一個匯點。

既然AOE網是表示工程流程的,所以就具有明顯的工程屬性。只有在某頂點代表的事件發生后,從該頂點出發的各活動才能開始。只有在進入某頂點的各活動都已經結束,該頂點代表的事件才能發生。

盡管AOV網和AOE網都是用來對工程建模的,但它們還是有很大的區別,主要體現在AOV網是頂點表示活動的網,它只描述活動之間的制約關系,而AOE網是用邊表示活動的網,邊上的權值表示活動持續的時間,如圖7-9-3所示兩圖的對比。因此,AOE網是要建立在活動之間制約關系沒有矛盾的基礎之上,再來分析完成整個工程需要多少時間,或者為縮短完成工程所需時間,應當加快哪些活動等問題。


我們把路徑上各個活動所持續的時間之后稱為路徑長度,從源點到匯點具有最大長度的路徑叫關鍵路徑,在關鍵路徑上完成的活動叫關鍵活動。顯然就圖7-9-3的AOE網而言,開始->發動機完成->部件集中到位->組裝完成就是關鍵路徑,路徑長度為5.5。

如果我們需要縮短整個工期,去改進輪子的生產效率,哪怕改動成0.1也無益于整個工期的變化,只有縮短關鍵路徑上的關鍵活動時間才才可以減少整個工期長度。例如如果發動機制造縮短為2.5,整車組裝縮短為1.5,那么關鍵路徑就為4.5,整整縮短了一天的時間。

如果某項活動的最早開始時間和最晚開始時間一樣,表示中間沒有空隙,則此項活動就為關鍵活動。為此,我們需要定義以下幾個參數。

1、事件的最早發生時間 etv(earliest time of vertex):即頂點vk 的最早發生時間。

2、事件的最晚發生時間 ltv(latest time of vertex):即頂點vk 的最短發生時間。也就是每個頂點對應的事件最晚需要開始的時間,超出此時間將會延誤整個工期。

3、活動的最早開工時間 ete (earliest time of edge):即弧ak 的最早發生時間。

4、活動的最晚開工時間 lte (latest time of edge ):即弧ak 的最晚發生時間,也就是不推遲工期的最晚開工時間。


我們首先求得1和2,而 ete 本來是表示活動<vk, vj> 的最早開工時間,是針對弧來說的,但只有此弧的弧尾頂點vk的事件發生了,它才可以開始,因此ete = etv[k]。

而lte 表示的是活動<vk, vj> 的最晚開工時間,但此活動再晚也不能等vj 事件發生才開始,所以lte = ltv[j] - len<vk, vj> 。

最終,我們再來判斷ete 和 lte 是否相等,相等意味著活動沒有任何空閑,是關鍵路徑,否則就不是。


現在來談談如何求etv 和 ltv。

假設我們現在已經求得頂點v0對應的 etv[0] = 0,頂點v1對應的etv[1] = 3, 頂點v2對應的etv[2] = 4, 現在我們需要求頂點v3對應的etv[3],其實就是求etv[1] + len<v1, v3> 與 etv[2] + len<v2, v3> 的較大值。顯然 3+5 < 4+8, 得到etv[3] = 12, 如圖7-9-5所示。


由此我們也可以得出計算頂點vk的最早發生時間即求etv[k]的公式是:


其中P[k] 表示所有到達頂點vk的弧的集合。比如圖7-9-5的P[3]就是<v1, v3> 和 <v2, v3> 兩條弧。len<vi, vk> 是弧<vi, vk>上的權值。


假如我們現在已經求得v9~ v5 頂點的ltv值,現在要求v4 的ltv 值,由鄰接表可得到v4 有兩條弧<v4, v6>, <v4, v7>,可以得到

ltv[4] = min(ltv[7] - 4, ltv[6] - 9) = 15,如圖7-9-8所示。


可以發現,在計算ltv時,其實是把拓撲序列倒過來進行而已,因此可以得到計算頂點vk最晚發生時間即求ltv[k] 的公式是:


其中S[K]表示所有從頂點vk出發的弧的集合。比如圖7-9-8的S[4] 就是<v4, v6>和<v4, v7>兩條弧,len<vk, vj> 是弧<vk, vj> 上的權值。

?

現有一AOE網圖如圖7-9-4所示,我們使用鄰接表存儲結構,注意與拓撲排序時鄰接表結構不同的地方在于,這里弧表結點增加了weight域,用來存儲弧的權值。


?

求解事件的最早發生時間etv的過程,就是我們從頭至尾找拓撲序列的過程,因此在求關鍵路徑之前,需要先調用一次拓撲序列算法的代碼來計算etv 和 拓撲序列列表,我們針對前面講過的AOV網與拓撲排序的程序進行改進,代碼如下(參考《大話數據結構》):

?

?

?

C++ Code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
?
/*?拓撲排序,若GL無回路,則輸出拓撲排序序列并返回1,若有回路返回0。?*/
bool?TopologicalSort(GraphAdjList?GL)
{
????EdgeNode?*pe;
????int?i,?k,?gettop;
????int?top?=?0;/*?用于棧指針下標??*/
????int?count?=?0;/*?用于統計輸出頂點的個數??*/
????/*?建棧將入度為0的頂點入棧??*/
????int?*stack?=?(int?*)malloc(GL->numVertexes?*?sizeof(int));

????for?(i?=?0;?i?<?GL->numVertexes;?i++)
????????if?(0?==?GL->adjList[i].in)
????????????stack[++top]?=?i;/*?將入度為0的頂點入棧?*/

????top2?=?0;
????etv?=?(int?*)malloc(GL->numVertexes?*?sizeof(int));
????for?(i?=?0;?i?<?GL->numVertexes;?i++)
????????etv[i]?=?0;?/*?初始化?*/
????stack2?=?(int?*)malloc(GL->numVertexes?*?sizeof(int));

????cout?<<?"TopologicalSort?..."?<<?endl;

????while?(top?!=?0)
????{
????????gettop?=?stack[top--];
????????cout?<<?GL->adjList[gettop].data?<<?"?->?";
????????count++;??/*?輸出i號頂點,并計數?*/

????????stack2[++top2]?=?gettop;?/*?將彈出的頂點序號壓入拓撲序列的棧?*/

????????for?(pe?=?GL->adjList[gettop].firstedge;?pe;?pe?=?pe->next)
????????{
????????????k?=?pe->adjvex;
????????????/*?將i號頂點的鄰接點的入度減1,如果減1后為0,則入棧?*/
????????????if?(!(--GL->adjList[k].in))
????????????????stack[++top]?=?k;
????????????/*?求各頂點事件的最早發生時間etv值?*/
????????????if?((etv[gettop]?+?pe->weight)?>?etv[k])
????????????????etv[k]?=?etv[gettop]?+?pe->weight;
????????}
????}
????cout?<<?endl;
????if?(count?<?GL->numVertexes)
????????return?false;
????else
????????return?true;
}

?


在程序開始處我們聲明了幾個全局變量:

int *etv,*ltv; /* 事件最早發生時間和最遲發生時間數組,全局變量 */
int *stack2; ? /* 用于存儲拓撲序列的棧 */
int top2; ? /* 用于stack2的指針 */

?

其中stack2用來存儲拓撲序列,以便后面求關鍵路徑時使用。

?

上面的拓撲排序函數中除了增加了第12~19行,29行,38~39行,其他跟前面講過的AOV網與拓撲排序沒什么區別。

?

第12~19行初始化全局變量etv數組、top2和stack2的過程。第29行就是將本來要輸出的拓撲序列壓入全局棧stack2中。第38~39行很關鍵,是求etv數組的每一個元素的值,具體求值辦法參見AOE網和關鍵路徑。

?


?

下面來看求關鍵路徑的算法代碼。

?

?

?

C++ Code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
?
/*?求關鍵路徑,GL為有向網,輸出G的各項關鍵活動?*/
void?CriticalPath(GraphAdjList?GL)
{
????EdgeNode?*pe;
????int?i,?j,?k,?gettop;
????int?ete,?lte;/*?聲明活動最早發生時間和最遲發生時間變量?*/
????TopologicalSort(GL);/*?求拓撲序列,計算數組etv和stack2的值?*/

????ltv?=?(int?*)malloc(GL->numVertexes?*?sizeof(int));?/*?事件最早發生時間數組?*/

????for?(i?=?0;?i?<?GL->numVertexes;?i++)
????????ltv[i]?=?etv[GL->numVertexes?-?1];/*?初始化?*/

????cout?<<?"etv?:??";
????for?(i?=?0;?i?<?GL->numVertexes;?i++)
????????cout?<<?etv[i]?<<?'?';
????cout?<<?endl;

????while?(top2?!=?0)/*?出棧是求ltv?*/
????{
????????gettop?=?stack2[top2--];
????????/*?求各頂點事件的最遲發生時間ltv值?*/
????????for?(pe?=?GL->adjList[gettop].firstedge;?pe;?pe?=?pe->next)
????????{
????????????k?=?pe->adjvex;
????????????if?(ltv[k]?-?pe->weight?<?ltv[gettop])
????????????????ltv[gettop]?=?ltv[k]?-?pe->weight;
????????}
????}

????cout?<<?"ltv?:??";
????for?(i?=?0;?i?<?GL->numVertexes;?i++)
????????cout?<<?ltv[i]?<<?'?';
????cout?<<?endl;
????/*?求ete,lte和關鍵活動?*/
????for?(j?=?0;?j?<?GL->numVertexes;?j++)
????{
????????for?(pe?=?GL->adjList[j].firstedge;?pe;?pe?=?pe->next)
????????{
????????????k?=?pe->adjvex;
????????????ete?=?etv[j];/*?活動最早發生時間?*/
????????????lte?=?ltv[k]?-?pe->weight;/*?活動最遲發生時間?*/
????????????if?(ete?==?lte)?/*?兩者相等即在關鍵路徑上?*/
????????????????cout?<<?"<v"?<<?GL->adjList[j].data?<<?"?-?v"
?????????????????????<<?GL->adjList[k].data?<<?">?length:?"?<<?pe->weight?<<?endl;
????????}
????}
}


函數第7行調用求拓撲序列的函數,執行完畢后,全局數組etv和棧stack2 如圖7-9-6所示,top2 = 10,也就是說,對于每個事件的最早發生時間,我們已經計算出來了。

?


?

第11~12行初始化全局變量ltv數組,因為etv[9] = 27,所以數組ltv值現在為全27。

?

第19~29行是計算ltv 數組的循環,具體方法參見AOE網和關鍵路徑。

?

當程序執行到第36行,etv和ltv數組的值如圖7-9-9

?


?

比如etv[1] = 3, 而ltv[1] = 7,表示如果單位是天的話,哪怕v1整個事件在第7天才開始,也可以保證整個工程的按期完成,可以提前v1事件開始時間,但最早也得第3天開始。

?

第36~47行是求另兩個變量,活動最早開始時間ete和活動最晚開始時間lte,并對相同下標的它們進行比較。兩重循環嵌套是對鄰接表的頂點和每個頂點的弧表遍歷,具體方法參見AOE網和關鍵路徑,舉例來說,如圖7-9-10,當j = 0時,當k = 2, ete = lte, 表示

?

弧<v0, v2> 是關鍵路徑,因此打印;當k = 1, ete != lte, 故弧<v0, v1> 不是關鍵路徑。

?


?

?


?

j = 1 一直到 j = 9為止,做法是完全相同的,最后輸出的結果如下圖,最終關鍵路徑如圖7-9-11所示。

?


?


?

?

轉載于:https://www.cnblogs.com/alantu2018/p/8471833.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/539366.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/539366.shtml
英文地址,請注明出處:http://en.pswp.cn/news/539366.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java 集合體系詳解——List體系有序集合

引言 面向對象語言對事物的體現必然是以對象的形式&#xff0c;Java工程師為了方便多多個對象的操作&#xff0c;就對對象進行存儲&#xff0c;集合就是存儲對象的一種方式&#xff0c;他們的底層都是基于不同的數據結構。當然集合和數組一樣都是容器&#xff0c;數組也是可以存…

android 定義固定數組,Android 圖片數組定義和讀取

位置&#xff1a;packages/apps/Launcher21、圖片數組定義、資源讀取如果有多張圖片&#xff0c;這些圖片的使用與順序無關&#xff0c;可以采取這種方式。drawable-nodpi中有3張圖片&#xff0c;wallpaper_1.jpg、wallpaper_2.jpg、wallpaper_3.jpgXML中定義數組IDwallpaper_1…

alert閃一下就沒了_尾部貫穿式鍍鉻銀飾條除了丑,還能閃瞎眼

尾部貫穿式鍍鉻銀飾條&#xff0c;在2010年代成為諸多汽車品牌車型爭相采用的新世紀新標配&#xff0c;配以雙邊排氣&#xff0c;讓整個車尾看起來層次感強烈&#xff0c;視覺收窄&#xff0c;幾十萬的奧迪A8L有&#xff0c;十幾萬的斯柯達速派有&#xff0c;A級車有&#xff0…

docker 指定網卡_Docker | Docker技術基礎梳理(五) Docker網絡管理

為什么需要容器的網絡管理&#xff1f;容器的網絡默認與宿主機、與其他容器相互隔離&#xff0c;且容器中可以運行一些網絡應用&#xff0c;比如nginx、web應用、數據庫等&#xff0c;如果需要讓外部也可以訪問這些容器中運行的網絡應用&#xff0c;那么就需要配置網絡來實現。…

java.net.URLEncode編碼 與 URLDecode解碼問題

原文&#xff1a;http://blog.csdn.net/luojian520025/article/details/9139293 -------------------------------------------------------------------------------------------- String mytext java.net.URLEncoder.encode("中國", "utf-8")…

Android安裝兩次才成功,Android應用從市場安裝完成打開與桌面打開,被啟動兩次的問題...

問題描述&#xff1a;1、從Android應用市場下載并安裝應用&#xff0c;安裝完成后&#xff0c;當前界面下方會出現“打開”按鈕&#xff0c;這時候我們點擊“打開”&#xff0c;會啟動應用&#xff0c;進入到應用的啟動頁面&#xff0c;然后進入應用的主界面&#xff0c;這個時…

事務保存點

在SQL Server中使用rollback會回滾所有的未提交事務狀態&#xff0c;但是有些時候我們只需要回滾部分語句&#xff0c;把不需要回滾的語句提到事務外面來&#xff0c;雖然是個方法&#xff0c;但是卻破壞了事務的ACID。 SQL中使用事務保存點 即可解決這個問題. 一.SQL 事務中存…

鼎信諾審計前端取數工具_給2019前端的5個建議

2019 農歷新年即將到來&#xff0c;是時候總結一下團隊過去一年的技術沉淀。過去一年我們支撐的數據相關業務突飛猛進&#xff0c;其中兩個核心平臺級產品代碼量分別達到30萬行和80萬行&#xff0c;TS 模塊數均超過1000個&#xff0c;協同開發人員增加到20人。由于歷史原因&…

Hadoop HA

HA概念&#xff1a; high avalability 高可用性。 hadoop 1.x非ha設計 Secondnode對元數據的可靠性有了保障&#xff0c;但服務的可用性不高。 即&#xff1a;當Namenode節點宕機了&#xff0c;整個hadoop就不能使用了&#xff0c;影響了client的使用。 hadoop 2.x的ha設計 新…

紫光展銳處理器有那些手機用_酷派將發千元5G手機,國產紫光展銳加持,主打性價比...

↑↑↑點擊上方藍字訂閱每日最新熱點手機資訊數年之前&#xff0c;“中華酷聯”是國產智能手機的四大代表。不過隨著越來越多的強力競爭者入局&#xff0c;中興、酷派、聯想漸漸衰敗&#xff0c;僅剩華為屹立手機行業頂端。但是酷派似乎從未想過放棄&#xff0c;最近便要發布一…

jelly bean android,Jelly Bean占Android系統份額突破10%

Android系統份額圖(騰訊科技配圖)騰訊科技訊(清雨)北京時間1月4日消息&#xff0c;據國外媒體報道&#xff0c;微博)周四發布最新數據顯示&#xff0c;Android 4.1版本和Android 4.2版本的Jelly Bean在Android系統中的份額超過了10%&#xff0c;另外Android 4.0版本的ICS的份額…

Unable to load native-hadoop library for your platform

警告&#xff1a; 16/08/04 19:21:36 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable 原因&#xff1a; 沒有配置好環境變量&#xff0c;hadoop的native沒有配置進去 解決方法&#x…

android網絡切換socket,Android版的websocket切換網絡無法重連

- 當前 Bug 的表現(可附上截圖)1、android微信使用websocket切換網絡時一般都無法重連&#xff0c;有時候重啟微信也沒用&#xff0c;需要重啟手機才能連上。移動或聯通網絡切換到電信網絡特別容易出現。2、Android微信使用socketIO經常會斷線重連&#xff0c;有時候斷線幾次就…

妲己機器人需要什么條件才能使用_estar零封YTG:平頭哥快樂電競,只有妲己沒亞瑟,差評...

2020KPL秋季賽常規賽第8周最后1個比賽日的第2場比賽&#xff0c;結果已經塵埃落定了。而最終的比賽結果是&#xff1a;estarpro輕松以3比0的大比分零封戰勝YTG。有一說一&#xff0c;這一場比賽真的是毫無懸念啊&#xff0c;甚至雙方交手的第1小局比賽&#xff0c;estarpro只用…

藍橋杯 出現次數最多的整數

問題描述   編寫一個程序&#xff0c;讀入一組整數&#xff0c;這組整數是按照從小到大的順序排列的&#xff0c;它們的個數N也是由用戶輸入的&#xff0c;最多不會超過20。然后程序將對這個數組進行統計&#xff0c;把出現次數最多的那個數組元素值打印出來。如果有兩個元素…

python離線錄音轉文字_Python將文字轉成語音并讀出來的實例詳解

前言 本篇文章主要介紹&#xff0c;如何利用Python來實現將文字轉成語音。將文字轉成語音主要有兩種不同的實現方法&#xff1a;先將文字轉成語音&#xff0c;然后再通過讀取語音實現發音、直接調用系統內置的語音引擎實現發音&#xff0c;后一種方法的實現主要利用第三方庫。 …

Linux 文件夾權限

文件夾默認權限&#xff1a;drwxr-xr-x 755 文件默認權限&#xff1a;-rw-r--r-- 644 ------------------------------------------ drwxr-xr-x 第一位(左數)表示當前目錄是目錄還是文件,d表示目錄,-表示普通文件. 后面9位分為3組,每3組作為1組, 從左到右分別表示&…

魅族15系統是android,魅族15系列評測:性能夠用王者榮耀優化

硬件性能&#xff1a;中配夠用&#xff0c;高配優秀硬件方面&#xff0c;文章前面的參數表已經寫得很清楚&#xff0c;魅族15搭載的是高通驍龍660處理器&#xff0c;并配備4GB的運行內存&#xff1b;魅族15 Plus則搭載三星Exynos 8895&#xff0c;配備6GB運行內存。在目前的移動…

.net 怎么循環得到數組里的值_HashMap 底層實現、加載因子、容量值及死循環

寫在前面&#xff1a;2020年面試必備的Java后端進階面試題總結了一份復習指南在Github上&#xff0c;內容詳細&#xff0c;圖文并茂&#xff0c;有需要學習的朋友可以Star一下&#xff01;GitHub地址&#xff1a;abel-max/Java-Study-NoteHashMap 簡介HashMap 是一個基于哈希表…

Linux下 -bash: php: command not found 命令找不到

轉載自CSDN博客&#xff0c;原作者&#xff1a;warthur。原文鏈接&#xff1a;http://blog.csdn.net/warthur/article/details/47342163這個問題其實很簡單&#xff0c;如果你在終端輸入一個命令&#xff0c;而系統提示你說命令沒有找到&#xff08;Command not found&#xff…