def toposort(graph):
vnum = graph.vertex_num()
indegree, toposeq = [0]*vnum, []
zerov = -1
for vi in range(vnum):
"""建立初始的入度表"""
for v,w in graph.out_edges(vi):
indegree[v] +=1
for vi in range(vnum):
"""建立初始的0度表"""
if indegree[vi]==0:
indegree[vi] = zerov
zerov = vi
for n in range(vnum):
if zerov == -1:
"""不存在拓扑序列"""
return False
vi = zerov # 从0度表弹出顶点vi
zerov = indegree[zerov]
toposeq.append(vi)
for v,w in graph.out_edges(vi):
indegree[v] -=1
if indegree[v] == 0:
indegree[v] = zerov
zerov = v
return toposeq
def critical_paths(graph):
def events_earliest_time(vnum,graph,toposeq):
ee = [0]*vnum
for i in toposeq:
for j, w in graph.out_edges(i):
if ee[i] + w > ee[j]: # 事件j更晚结束?
ee[j] = ee[i] + w
return ee
def event_latest_time(vnum,graph,toposeq,eelast):
le = [eelast]*vnum
for k in range(vnum-2,-1,-1): # 逆拓扑排序
i = toposeq[k]
for j,w in graph.out_edges(i):
if le[j] - w < le[i]: # 事件i应更早开始
le[i] = le[j] - w
return le
def crt_paths(vnum,graph,ee,le):
crt_actions = []
for i in range(vnum):
for j, w in graph.out_edges(i):
if ee[i] == le[j]-w: # 关键活动
crt_actions.append((i,j,ee[i]))
return crt_actions
toposeq = toposort(graph)
if not toposeq: # 不存在拓扑序列,失败,结束
return False
vnum = graph.vertex_num()
ee = events_earliest_time(vnum,graph,toposeq)
le = event_latest_time(vnum,graph,toposeq,ee[vnum-1])
return crt_paths(vnum,graph,ee,le)