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

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

求关键路径的算法:
(1)输入e条弧(j,k),建立AOE网;
(2)从源点 v 0 v_0 v0出发,令ve[0] = 0,按照拓扑排序求其余各个顶点的最早发生时间ve[i],(i <= i <= n-1)。如果得到的拓扑有序序列中顶点的个数小于网中的顶点数n,则说明网中存在环,不能求关键路径,算法终止;否则执行步骤三;
(3)从汇点 v n v_n vn出发,令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(最迟发生时间)
A Ve(A)=0 VI(A) =MIN( Vl(B)-c(a1) , Vl( C C C)-c(a2) , Vl(D)-c(a3) ) = MIN(6-6,6-4,12-5) =MIN(0,2,7) =0
B Ve(B)=Ve(A)+c(a1) = 0+6 =6 VI(B) = VI(E)-c(a4)=7-1=6
C Ve( C C C)=Ve(A)+c(a2) = 0+4 =4 VI( C C C) = VI(E)-c(a5)=7-1=6
D Ve(D)= Ve(A)+c(a3) = 0+5 =5 VI(D) = VI(H)-c(a6)=14-2=12
E Ve(E)=MAX( Ve(B)+c(a4) , Ve( C C C)+c(a5) ) = MAX(6+1,4+1) = 7 VI(E) =MIN( Vl(F)-c(a7) , Vl(G)-c(a8) ) = MIN(16-9,14-7) =MIN(7,7) =7
F Ve(F)= Ve(E)+c(a7) =7+9=16 VI(F) = VI(I)-c(a10)=18-2=16
G Ve(G)= Ve(E)+c(a8)=7+7=14 VI(G) = VI(I)-c(a11)=18-4=14
H Ve(H)=Ve(D)+c(a6)=5+2=7 VI(H) = VI(I)-c(a9)=18-4=14
I Ve(I)=MAX( Ve(F)+c(a10) , Ve(G)+c(a11) ,Ve(H)+c(a9)) = MAX(16+2,14+4,7+4) = 18 VI(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)时间余量
a1 e(a1)=Ve(A)=0 l(a1)=Vl(B)-6=6-6-0 d(a1)=0-0=0
a2 e(a2)= Ve(A)=0 l(a2)=VI( C C C<
  • 7
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
关键路径算法是一种用于确定项目完成所需时间的技术,其重点在于出各个活动的最早开始时间、最晚开始时间、总时差和自由时差。在实现时采用邻接表存储有向无环(DAG),具体代码如下: ```python from collections import defaultdict class Graph: def __init__(self, vertices): self.graph = defaultdict(list) self.vertices = vertices self.indegree = [0] * vertices self.topo_order = [] self.start_time = [0] * vertices self.end_time = [0] * vertices self.critical_path = [] def add_edge(self, u, v, weight): self.graph[u].append((v, weight)) self.indegree[v] += 1 def get_indegree(self, v): return self.indegree[v] def get_topo_order(self): return self.topo_order def get_start_time(self, v): return self.start_time[v] def get_end_time(self, v): return self.end_time[v] def get_critical_path(self): return self.critical_path def topological_sort(self): queue = [] for i in range(self.vertices): if self.indegree[i] == 0: queue.append(i) while queue: u = queue.pop(0) self.topo_order.append(u) for v, weight in self.graph[u]: self.indegree[v] -= 1 if self.indegree[v] == 0: queue.append(v) self.start_time[v] = max(self.start_time[v], self.end_time[u]) self.end_time[u] = max(self.end_time[u], self.start_time[u] + weight) def find_critical_path(self): for u in range(self.vertices): for v, weight in self.graph[u]: if self.start_time[u] + weight == self.start_time[v]: self.critical_path.append((u, v, weight)) if __name__ == '__main__': g = Graph(7) g.add_edge(0, 1, 3) g.add_edge(0, 2, 2) g.add_edge(1, 3, 4) g.add_edge(2, 3, 2) g.add_edge(3, 4, 4) g.add_edge(3, 5, 3) g.add_edge(4, 6, 2) g.add_edge(5, 6, 1) g.topological_sort() g.find_critical_path() print("Topological order:", g.get_topo_order()) print("Start time:", g.start_time) print("End time:", g.end_time) print("Critical path:", g.get_critical_path()) ``` 在上述代码中,我们首先定义了一个 Graph 类,其中包含邻接表、顶点数、每个顶点的入度、拓扑排序后的顺序、每个顶点的最早开始时间、最晚开始时间、关键路径等信息。然后定义了一些方法,包括添加边、获取入度、获取拓扑排序后的顺序、获取最早开始时间、最晚开始时间和关键路径等。其中,topological_sort() 方法实现了拓扑排序,find_critical_path() 方法实现查找关键路径。 在主函数中,我们定义了一个 7 个顶点的 DAG,并添加了各个顶点之间的边。然后调用 topological_sort() 方法进行拓扑排序,再调用 find_critical_path() 方法查找关键路径。最后输出了拓扑排序后的顺序、每个顶点的最早开始时间、最晚开始时间和关键路径等信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值