python拓扑排序与关键路径

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)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值