当前位置: 首页>編程日記>正文

图之查找关键路径(python)实现

图之查找关键路径(python)实现

与AOV-网对应的是AOE-网(Activity on Edge)即便表示活动的网。AOE网是一个带权的有向无环图,其中,顶点表示事件,弧表示活动持续的时间。通常,AOE网可以用来估算工程的完成时间。
由于AOE网中的有些活动是可以并行进行的,所以完成整个工程的最短时间是从开始点到完成点的最长路径长度(这里所说的路径长度是指路径上各活动的持续时间之和,不是路径上弧的数目。)路径长度最长的路径叫做关键路径。

求关键路径的算法:
(1)输入e条弧(j,k),建立AOE网;
(2)从源点v0v_0v0出发,令ve[0] = 0,按照拓扑排序求其余各个顶点的最早发生时间ve[i],(i <= i <= n-1)。如果得到的拓扑有序序列中顶点的个数小于网中的顶点数n,则说明网中存在环,不能求关键路径,算法终止;否则执行步骤三;
(3)从汇点vnv_nvn出发,令vl[n-1] = ve[n-1],按照逆拓扑有序求其余各顶点的最迟发生时间vl[i],(n-2 >= i >= 2);
(4)根据各顶点的ve和vl值,求每条弧s的最早开始时间e(s)和最迟开始时间l(s)。若某条弧满足条件e(s) = l(s),则为关键活动。

那到底如何来求呢?我们来看看例子。

首先先解释下上面提到的结果名次词:
顶点表示事件(能被触发,最早发生时间Ve(j);最晚发生时间Vl(j));
边表示活动(能被开始,最早开始时间e(i);最晚开始时间l(i))

并且AOE网中的点和边遵循两个原则:
(1)只有某顶点所代表事件发生后,从该顶点出发的各活动才能开始
(2)只有进入某顶点的各活动都结束,该顶点所代表的事件才能发生

现在那知道了点和边的属性,怎样计算关键路径呢?
计算关键路径:

计算关键路径,只需求出上面的四个特征属性,然后取e(i)=l(i)的边即为关键路径上的边(关键路径可能不止一条)。

下面我们来计算一个例图的关键路径:
在这里插入图片描述
下面我们来计算各事件的:
Ve(v):最早发生时间:是指从始点开始到顶点Vk的最大路径长度
   (1)从前向后,取大值:直接前驱结点的Ve(j)+到达边(指向顶点的边)的权值,有多个值的取较大者
   (2)首结点Ve(j)已知,为0

Vl(v):最迟发生时间:在不推迟整个工期的前提下,事件vk允许的最晚发生时间 
(1)从后向前,取小值:直接后继结点的Vl(j) –发出边(从顶点发出的边)的权值,有多个值的取较小者;
(2)终结点Vl(j)已知,等于它的Ve(j))

顶点(事件)Ve(最早发生时间)VL(最迟发生时间)
AVe(A)=0VI(A) =MIN( Vl(B)-c(a1) , Vl(CCC)-c(a2) , Vl(D)-c(a3) ) = MIN(6-6,6-4,12-5) =MIN(0,2,7) =0
BVe(B)=Ve(A)+c(a1) = 0+6 =6VI(B) = VI(E)-c(a4)=7-1=6
CVe(CCC)=Ve(A)+c(a2) = 0+4 =4VI(CCC) = VI(E)-c(a5)=7-1=6
DVe(D)= Ve(A)+c(a3) = 0+5 =5VI(D) = VI(H)-c(a6)=14-2=12
EVe(E)=MAX( Ve(B)+c(a4) , Ve(CCC)+c(a5) ) = MAX(6+1,4+1) = 7VI(E) =MIN( Vl(F)-c(a7) , Vl(G)-c(a8) ) = MIN(16-9,14-7) =MIN(7,7) =7
FVe(F)= Ve(E)+c(a7) =7+9=16VI(F) = VI(I)-c(a10)=18-2=16
GVe(G)= Ve(E)+c(a8)=7+7=14VI(G) = VI(I)-c(a11)=18-4=14
HVe(H)=Ve(D)+c(a6)=5+2=7VI(H) = VI(I)-c(a9)=18-4=14
IVe(I)=MAX( Ve(F)+c(a10) , Ve(G)+c(a11) ,Ve(H)+c(a9)) = MAX(16+2,14+4,7+4) = 18VI(I) = Ve(I) = 18

下面来计算各活动的:
e(v):最早发生时间:
若活动ai由弧<vk,vj>表示,则活动ai的最早开始时间应该等于事件vk的最早发生时间。因而,有:e[i]=ve[k];(即:边(活动)的最早开始时间等于,它的发出顶点的最早发生时间)

l(v):最迟发生时间:
若活动ai由弧<vk,vj>表示,则ai的最晚开始时间要保证事件vj的最迟发生时间不拖后。 因而有:l[i]=vl[j]-len<vk,vj>1(为边(活动)的到达顶点的最晚发生时间减去边的权值)

**d(v):活动时间余量:**d(v) = l(v) - e(v)

边(活动)e(V)最早发生时间l(v)最晚发生时间d(v)时间余量
a1e(a1)=Ve(A)=0l(a1)=Vl(B)-6=6-6-0d(a1)=0-0=0
a2e(a2)= Ve(A)=0l(a2)=VI(CCC)-4=6-4=2d(a2)=2-0=2
a3e(a3)= Ve(A)=0l(a3)=Vl(D)-5=12-5=7d(a3)=7-0=7
a4e(a4)=Ve(B)=6l(a4)=Vl(E)-1=7-1=6d(a4)=6-6=0
a5e(a5)=Ve(CCC)=4l(a5)=Vl(E)-1=7-1=6d(a5)=6-4=2
a6e(a6)=Ve(D)=5Ve(D)=5l(a6)=Vl(H)-2=14-2=12d(a6)=12-5=7
a7e(a7)=Ve(E)=7l(a7)=Vl(F)-9=16-9=7d(a7)=7-7=0
a8e(a8)=Ve(E)=7l(a8)=Vl(G)-7=14-7=7d(a8)=7-7=0
a9e(a9)=Ve(H)=7Ve(H)=7l(a9)=Vl(I)-4=18-4=14d(a9)=14-7=7
a10e(a10)=Ve(F)=16l(a10)=Vl(I)-2=18-2=16d(a10)=16-16=0
a11e(a11)=Ve(G)=14l(a11)=Vl(I)-4=18-4=14d(a11)=14-14=0

那么由上表可知:d(v)等于0的为关键活动,所以a1,a4,a7,a8,a10,a11所表示的活动为关键路径:
在这里插入图片描述

至此,我们得到了关键路径:A-B,B-E,E-F,E-G,F-I,G-I。

下面我们用代码来实现该过程:

def find_shorted_path():#顶点列表node_list = ['A','B','C','D','E','F','G','H','I']edge_list = [['A','B',  6],['A', 'C', 4],['A', 'D', 5],['B', 'E', 1],['C', 'E', 1],['D', 'H', 2],['E', 'F', 9],['E', 'G', 7],['F', 'I', 2],['G', 'I', 4],['H', 'I', 4],]'''计算各个顶点的Ve(v)最早发生时间'''#找出图的起点temp_start_list = []for edge in edge_list:temp_start_list.append(edge[1])start_node = [x for x in node_list if x not in temp_start_list]# print(start_node)Ve_node_dict = {}Ve_node_dict[start_node[0]] = 0for node in node_list:Ve_tempnode_list = []for edge in edge_list:if node == edge[1]:temp_Ve_node_value = Ve_node_dict[edge[0]] + edge[2]Ve_tempnode_list.append(temp_Ve_node_value)if len(Ve_tempnode_list) == 0:Ve_node_dict[node] = 0if len(Ve_tempnode_list) == 1:Ve_node_value = Ve_tempnode_list[0]Ve_node_dict[node] = Ve_node_valueif len(Ve_tempnode_list) > 1:Ve_node_value = max(Ve_tempnode_list)Ve_node_dict[node] = Ve_node_valueprint('Ve(v)最早发生时间:\n',Ve_node_dict,'\n')'''计算各个顶点的Vl(v)最迟发生时间'''#找出图的终点temp_end_list = []for edge in edge_list:temp_end_list.append(edge[0])end_node = [x for x in node_list if x not in temp_end_list]# print(end_node)Vl_node_dict = {}Vl_node_dict[end_node[0]] = Ve_node_dict[end_node[0]]reverse_edge_list = []for i in range(len(edge_list)-1,-1,-1):reverse_edge_list.append(edge_list[i])for node in reversed(node_list):Vl_tempnode_list = []for edge in reverse_edge_list:if node == edge[0]:temp_Vl_node_value = Vl_node_dict[edge[1]] - edge[2]Vl_tempnode_list.append(temp_Vl_node_value)if len(Vl_tempnode_list) == 0:Vl_node_dict[node] = Ve_node_dict[end_node[0]]if len(Vl_tempnode_list) == 1:Vl_node_value = Vl_tempnode_list[0]Vl_node_dict[node] = Vl_node_valueif len(Vl_tempnode_list) > 1:Vl_node_value = min(Vl_tempnode_list)Vl_node_dict[node] = Vl_node_valueprint('Vl(v)最迟发生时间:\n',Vl_node_dict,'\n')'''计算各个边的e(a)最早发生时间'''e_bian_dict = {}for edge in edge_list:e_bian_dict['{}-{}'.format(edge[0],edge[1])] = Ve_node_dict[edge[0]]print('e(a)最早发生时间:\n',e_bian_dict,'\n')'''计算各个边的l(a)最迟发生时间'''l_bian_dict = {}for edge in edge_list:l_bian_dict['{}-{}'.format(edge[0],edge[1])] = Vl_node_dict[edge[1]] - edge[2]print('l(a)最迟发生时间:\n',l_bian_dict,'\n')'''计算时间余量d(a)'''d_bian_dict = {}for bian in e_bian_dict.keys():d_bian_dict[bian] = l_bian_dict[bian] - e_bian_dict[bian]print("d(a)时间余量:\n",d_bian_dict,'\n')print("关键路径为:",[x for x in d_bian_dict if d_bian_dict[x] == 0])if __name__ == "__main__":find_shorted_path()

运行结果:

Ve(v)最早发生时间:{'A': 0, 'B': 6, 'C': 4, 'D': 5, 'E': 7, 'F': 16, 'G': 14, 'H': 7, 'I': 18} Vl(v)最迟发生时间:{'I': 18, 'H': 14, 'G': 14, 'F': 16, 'E': 7, 'D': 12, 'C': 6, 'B': 6, 'A': 0} e(a)最早发生时间:{'A-B': 0, 'A-C': 0, 'A-D': 0, 'B-E': 6, 'C-E': 4, 'D-H': 5, 'E-F': 7, 'E-G': 7, 'F-I': 16, 'G-I': 14, 'H-I': 7} l(a)最迟发生时间:{'A-B': 0, 'A-C': 2, 'A-D': 7, 'B-E': 6, 'C-E': 6, 'D-H': 12, 'E-F': 7, 'E-G': 7, 'F-I': 16, 'G-I': 14, 'H-I': 14} d(a)时间余量:{'A-B': 0, 'A-C': 2, 'A-D': 7, 'B-E': 0, 'C-E': 2, 'D-H': 7, 'E-F': 0, 'E-G': 0, 'F-I': 0, 'G-I': 0, 'H-I': 7} 关键路径为: ['A-B', 'B-E', 'E-F', 'E-G', 'F-I', 'G-I']

与手动查找的关键路径相同。

本文原创,转载请注明出处!!!


https://www.fengoutiyan.com/post/13999.html

相关文章:

  • python定位图片坐标
  • 用拓扑排序求关键路径
  • python如何在列表中查找元素位置
  • python为什么叫爬虫
  • python列表查找元素
  • 关键路径定义
  • python 找图
  • 求关键路径的算法
  • 鏡像模式如何設置在哪,圖片鏡像操作
  • 什么軟件可以把圖片鏡像翻轉,C#圖片處理 解決左右鏡像相反(旋轉圖片)
  • 手機照片鏡像翻轉,C#圖像鏡像
  • 視頻鏡像翻轉軟件,python圖片鏡像翻轉_python中鏡像實現方法
  • 什么軟件可以把圖片鏡像翻轉,利用PS實現圖片的鏡像處理
  • 照片鏡像翻轉app,java實現圖片鏡像翻轉
  • 什么軟件可以把圖片鏡像翻轉,python圖片鏡像翻轉_python圖像處理之鏡像實現方法
  • matlab下載,matlab如何鏡像處理圖片,matlab實現圖像鏡像
  • 圖片鏡像翻轉,MATLAB:鏡像圖片
  • 鏡像翻轉圖片的軟件,圖像處理:實現圖片鏡像(基于python)
  • canvas可畫,JavaScript - canvas - 鏡像圖片
  • 圖片鏡像翻轉,UGUI優化:使用鏡像圖片
  • Codeforces,CodeForces 1253C
  • MySQL下載安裝,Mysql ERROR: 1253 解決方法
  • 勝利大逃亡英雄逃亡方案,HDU - 1253 勝利大逃亡 BFS
  • 大一c語言期末考試試題及答案匯總,電大計算機C語言1253,1253《C語言程序設計》電大期末精彩試題及其問題詳解
  • lu求解線性方程組,P1253 [yLOI2018] 扶蘇的問題 (線段樹)
  • c語言程序設計基礎題庫,1253號C語言程序設計試題,2016年1月試卷號1253C語言程序設計A.pdf
  • 信奧賽一本通官網,【信奧賽一本通】1253:抓住那頭牛(詳細代碼)
  • c語言程序設計1253,1253c語言程序設計a(2010年1月)
  • 勝利大逃亡英雄逃亡方案,BFS——1253 勝利大逃亡
  • 直流電壓測量模塊,IM1253B交直流電能計量模塊(艾銳達光電)
  • c語言程序設計第三版課后答案,【渝粵題庫】國家開放大學2021春1253C語言程序設計答案
  • 18轉換為二進制,1253. 將數字轉換為16進制
  • light-emitting diode,LightOJ-1253 Misere Nim
  • masterroyale魔改版,1253 Dungeon Master
  • codeformer官網中文版,codeforces.1253 B
  • c語言程序設計考研真題及答案,2020C語言程序設計1253,1253計算機科學與技術專業C語言程序設計A科目2020年09月國家開 放大學(中央廣播電視大學)
  • c語言程序設計基礎題庫,1253本科2016c語言程序設計試題,1253電大《C語言程序設計A》試題和答案200901
  • 肇事逃逸車輛無法聯系到車主怎么辦,1253尋找肇事司機