title: AOE网及关键路径实现
date: 2019-09-03 19:46:30
tags: python,数据结构
categories: 计算机理论
关键路径
算法原理
AOE网是另一种常用的带权有向图。这是一种重要的PERT模型(Program Evaluation and Review Technique,规划评估和评审技术),最早是美国军方支持开发出来的,用于大型工程的计划与管理,有着广泛的实际工程应用。
抽象地看:AOE网是一种无环的带权有向图,其中
- 顶点表示事件,有向边表示活动,边上的权值通常表示活动的持续时间。
- 图中的一个顶点表示的事件,也就是他的入边所表示的活动已经完成,他的出边的活动刚刚开始,把这一情况看作事件。
实际工程或复杂事物里的一批相关活动(工作项目、任务等),可以用一个AOE网抽象的描述,然后就可以基于这个网考虑活动的安排了。
算法实现
# 关键路径
def criticalPath(self, delay=0):
topo = self.topological_sort()
if not topo:
raise GraphError("存在有向环!")
ve = [0 for i in range(len(topo))] # 事件最早开始时间
vl = [0 for i in range(len(topo))] # 事件最迟开始时间
cp = [] # 关键路径
result = {
} # 返回结果
# --------------------------------计算事件的最早发生时间-----------------------------
for i in range(topo.__len__()):
start = topo[i] # 取出拓扑节点
for node in self.get_outEdge(start).keys(): # 获取拓扑节点的邻接点,计算ve
w = self._graph[start][node] # 当前节点与邻接节点的边
j = topo.index(node) # 邻接节点的下标
if ve[j] < ve[i] + w: # 更新邻接点的最早发生时间,选大的时间
ve[j] = ve[i] + w
pass
# --------------------------------计算事件的最晚发生时间-----------------------------
for i in range(topo.__len__()): # 给每个事件的最迟发生时间置初值,初值为最早发生时间中的最大值
vl[i] = ve[topo.__len__() - 1] + delay
for i in reversed(range(topo.__len__())):
k = topo[i] # 取出拓扑节点
for node in self.get_inEdge(k).keys(): # 获取拓扑节点的逆邻接点,计算vl
w = self._graph[node][k] # 逆邻接点和当前节点的边
j = topo.index(node) # 逆邻接点的下标
if vl[j] > vl[i] - w: # 更新逆邻接点的最晚发生时间,选小的时间
vl[j] = vl[i] - w
pass
# --------------------------------判断每一活动是否为关键路径--------------------------
for i in range(topo.__len__()):
start = topo[i]
for node in self.get_outEdge(start).keys():
j = topo.index(node) # 获得邻接顶点的下标
w = self._graph[start][node] # 当前节点与邻接节点的边
e = ve[i] # 计算活动<start,node>的最早开始时间
l = vl[j] - w - delay # 计算活动<start,node>的最晚开始时间
if e == l:
cp.append((start, node)) # 如果相等就说明为关键路径
pass
for i in range(topo.__len__()):
result[topo[i]] = (ve[i], vl[i])
pass
return result, cp