原文链接:http://www.psme.foothill.edu/wp-content/uploads/2014/04/AOE-Network.pdf
上面就是AOE网,边:Activity,顶点:Event
简而言之,就是earliest time和latest time的定义,两者都是基于Activity的,就是字面意思,但是都是(最早/最晚)开始时间
还定义了
关键Activity
对于Activity a_i,它对应的边是
则可以这样计算e(i)和l(i),通过下面的公式:
也就是:
活动i的最早时间 = 头节点的最早时间;
活动i的最晚时间 = 尾节点的最晚时间 - 活动i的持续时间;
也就是将e(i)和l(i)转换到计算Event的ee值和le值上面去,这两个值就是最早时间和最晚时间,它们可以用“向前计算”+“向后计算”的两个步骤得到:
“向前计算”阶段:首先我们能得到ee[0],从而计算后面节点的开始时间,使用下面的公式:
ee[j] = max { ee[i] + DURATION(a) }, 其中j节点是i节点的后继节点
后继节点就是有边从i节点指向的节点,而且上面的公式对所有后继节点都适用。
如果按照拓扑顺序,对于j节点的所有前驱节点,我们都要计算出来它们的最早时间,才能计算出来ee[j]
而计算方式,就是从项目的开始节点start,逐步向后,使用上面的公式计算,注意公式当中的max规约
不上代码了,代码对原始算法思想做了内存空间优化,也不上伪代码,受限制于Stack结构和节点的数据结构定义,我们用最简单的方法:
1.将start节点加入集合S,ee(start)=xxx;
2.对于集合外的节点,如果它的前驱节点全部在集合内,那么根据max规约,求出它的ee值,并放入集合S;
3.重复上述步骤,直到所有节点都在集合S内;
ee(finish)就是我们要求的critical path的长度;
如果还是不懂,看下面的英文分析,尤其是后面那张表:
“向前计算”结束了,开始“向后计算”:
首先,“向后计算”的前提条件,不再是“所有前驱节点的ee值都已经算出”,而是“所有后继节点的le值都已经计算出”;
算法:
1.将finish节点加入集合S,le(finish) = ee(finish);
2.对于集合外的节点,如果它的后继节点全部在集合内,那么根据min规约,求出它的le值,并放入集合S;
3.重复上述步骤,直到所有节点都在集合S内;
我们给出了表格:
再根据规则:
活动i的最早时间 = 头节点的最早时间;
活动i的最晚时间 = 尾节点的最晚时间 - 活动i的持续时间;
可以得到各个Activity的 最早/最晚时间,以及关键活动: