题目
下图是一个软件开发项目的活动图,对于图中每条边的数字表示完成这条边代表的活动的天数。例如,完成终止于里程碑E的活动需要 4 天时间。
对于每个活动,列出它的前驱,并计算最早开始时间、最晚开始时间和时差,然后确定出关键路径。
—— 《软件工程 第 4 版》中的原题
写文缘由
网上的文章大都是对于 “点” 求最早开始时间和最晚开始时间。在我看来,是不准确的。
对于边的解法,有的写得又太复杂,还是自己写吧。顺便写个程序自动化一下,舒服~
误区在哪
需要注意的是,图中的点,并不代表活动,并不能说活动 A A A 用 3 3 3 天到达活动 B B B,这是不准确的,图上的点应该理解为 “里程碑”。如果说到达 里程碑 I I I 的边有两条 D → I D \rightarrow I D→I 和 B → I B \rightarrow I B→I,意思是有两个活动,完成后到达里程碑 I I I,并不能说 I I I 是个活动,如果这么理解会在计算最晚开始时间时出现错误。
还有一点,时间轴从 1 1 1 开始算,即从点 A A A 出发时,时刻为 1 1 1。有些解法是从 0 0 0 开始算的,本文从 1 1 1 开始算。
解法
- 正推求最早开始时间
- 公式: ET B ⋅ = MAX ( ET A B + w A B ) \text{ET}_{B·} = \text{MAX}(\text{ET}_{AB} + w_{AB} ) ETB⋅=MAX(ETAB+wAB)
- 已知条件:起点的最早开始时间直接为 1
- 倒推求最晚开始时间
- 公式: LT J K = MIN ( LT K ⋅ − w J K ) \text{LT}_{JK} = \text{MIN}(\text{LT}_{K·} - w_{JK} ) LTJK=MIN(LTK⋅−wJK)
- 已知条件:终点的最晚开始时间 LT L ⋅ = ET L ⋅ \text{LT}_{L·}=\text{ET}_{L·} LTL⋅=ETL⋅ (因为终点一定在关键路径上,关键路径上的点最早开始时间等于最晚开始时间)
解题示例
解:
先求最早开始时间 (Earliest Time Start):
- A A A 是起点,所有由 A A A 出发的边的最早开始时间都为 1 1 1。即 ET A B = ET A E = ET A C = ET A ⋅ = 1 \text{ET}_{AB} = \text{ET}_{AE} = \text{ET}_{AC} =\text{ET}_{A·}= 1 ETAB=ETAE=ETAC=ETA⋅=1
- 来算 B B B 的最早开始时间, ET B D = ET B I = ET B ⋅ = MAX ( ET A B + w A B ) = 4 \text{ET}_{BD} = \text{ET}_{BI} = \text{ET}_{B·} =\text{MAX}(\text{ET}_{AB}+w_{AB}) =4 ETBD=ETBI=ETB⋅=MAX(ETAB+wAB)=4。因为只有 A A A 才能到达 B B B,所以 MAX 内只有一个值。
- 来算 E E E 的最早开始时间, ET E G = MAX ( ET A E + w A E ) = 5 \text{ET}_{EG} =\text{MAX}(\text{ET}_{AE}+w_{AE}) =5 ETEG=MAX(ETAE+wAE)=5。因为只有 A A A 才能到达 E E E,所以 MAX 内只有一个值。
- 来算 C C C 的最早开始时间, ET C F = MAX ( ET A C + w A C ) = 6 \text{ET}_{CF} =\text{MAX}(\text{ET}_{AC}+w_{AC}) =6 ETCF=MAX(ETAC+wAC