上篇博客我们介绍了AOV网的拓扑序列,请参考《数据结构(七) AOV网的拓扑排序(Swift面向对象版)》。拓扑序列中包括项目的每个结点,沿着拓扑序列将项目进行下去是肯定可以将项目完成的,但是工期不是最优的。因为拓扑序列是一个串行序列,如果按照该序列执行项目,那么就是串行执行的。我们知道在一个项目中的一些子工程是可以并行来完成的,这也就类似我们的多线程。今天我们要解决的问题就是找出一个关键路径,是工期最优并保证工程的完成。什么是关键路径,我们在下方会进行详细介绍。
一、关键路径概述
在聊关键路径之前,我们先看一个简单的实例,如下图所示。我们将下方这个有向无环图看做是整个工程,将每个节点看做是该项目工程的一个子工程。子工程间又有一定的优先级。在下方图中,A的优先级最高。A做完后,B、C才可以进行开发。B、C完成后,我们才可以开发D。从下图中我们不难看出,该图的拓扑序列为A, B, C, D。如果我们按照串行的方式来完成此工程的话,那么工程完成的顺序可以是A-5->B, A-8->C, B-3->D, C-10->D。总时间为26。
从上面这个序列中我们显然可以看出来这不是最优的,因为A->B, A->C可以同时进行,B->D和C->D也可以同时进行。在允许某些子工程同时进行的情况下,A->B和A-C可以同时进行,因为A->B所需时间小于A->C所需时间,所以我们选择A->C。在A->C执行这8个小时的时间里,A->B和B->D已经执行完了,就剩下C->D了,所以关键工期为A->C->D=18。
在求关键路径的算法中,我们先求出每个事件的最早完成时间。在事件最早完成的时间集合中,工程最后一步完成的时间就是我们工程完成的最优时间。然后在工程时间最优的情况下求出每个事件最晚完成时间。如果某个时间最早的完成时间与最晚的完成时间相同,那么该事件就是我们的关键事件,该事件就位于我们关键路径中。如果这样叙述有些抽象,那么我们就拿下方这个简单图来做个类比。
在上方这个有向无环图中,我们可以求出每个事件最早发生的时间。下方截图就是每个事件所对应的最早完成的事件,因为D是工程的尾结点,所以该工程完成的最早

