AOE网及关键路径实现


title: AOE网及关键路径实现
date: 2019-09-03 19:46:30
tags: python,数据结构
categories: 计算机理论

关键路径

算法原理

AOE网是另一种常用的带权有向图。这是一种重要的PERT模型(Program Evaluation and Review Technique,规划评估和评审技术),最早是美国军方支持开发出来的,用于大型工程的计划与管理,有着广泛的实际工程应用。

抽象地看:AOE网是一种无环的带权有向图,其中

  • 顶点表示事件,有向边表示活动,边上的权值通常表示活动的持续时间。
  • 图中的一个顶点表示的事件,也就是他的入边所表示的活动已经完成,他的出边的活动刚刚开始,把这一情况看作事件。

实际工程或复杂事物里的一批相关活动(工作项目、任务等),可以用一个AOE网抽象的描述,然后就可以基于这个网考虑活动的安排了。

6
4
5
1
1
2
9
7
4
2
4
V0
V1
V2
V3
V4
V5
V6
V7
V8

算法实现

    # 关键路径
    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

测试

6
4
5
1
1
2
9
7
4
2
4
V0
V1
V2
V3
V4
V5
V6
V7
V8

20190831212504

猜你喜欢

转载自blog.csdn.net/weixin_41154636/article/details/100527012