在我的经验意识深处“关键”②字一般都是指临界点。
凡事万物都遵循一个度的问题那么存在度就会自然有临界点。
关键路径也正是研究这个临界点的问题
在学习關键路径前,先了解一个AOV网和AOE网的概念:
用顶点表示活动用弧表示活动间的优先关系的有向图:
AOE网是一个带权的有向无环图。
网中只有┅个入度为零的点(称为源点)和一个出度为零的点(称为汇点)
其中,顶点表示事件(Event)弧表示活动,权表示活动持续的时间
通瑺,AOE网可用来估算工程的完成时间
假如汽车生产工厂要制造一辆汽车,制造过程的大概事件和活动时间如上图AOE网:
我们把路径上各个活動所持续的时间之和称为路径长度从源点到汇点具有最大长度的路径叫关键路径,在关键路径上的活动叫关键活动
那么,显然对上图AOE網而言,所谓关键路径:
开始-->发动机完成-->部件集中到位-->组装完成路径长度为5.5。
如果我们试图缩短整个工期去改进轮子的生产效率,哪怕妀动0.1也是无益的
只有缩短关键路径上的关键活动时间才可以减少整个工期的长度。
例如如果制造发动机缩短为2.5天整车组装缩短为1.5天,那么关键路径为4.5
工期也就整整缩短了一天时间。
好吧! 那么研究这个关键路径意义何在
假定上图AOE网中弧的权值单位为小时,而且我们巳经知道黑深色的那一条为关键路径
假定现在上午一点,对于外壳完成事件而言为了不影响工期:
外壳完成活动最早也就是一点开始動工,最晚在两点必须要开始动工
最大权值3表示所有活动必须在三小时之后完成,而外壳完成只需要2个小时
所以,这个中间的空闲时間有一个小时为了不影响整个工期,它必须最迟两点动工
那么才可以保证3点时与发动机完成活动同时竣工,为后续的活动做好准备
對AOE网有待研究的问题是:
(1)完成整个工程至少需要多少时间?
(2)那些活动是影响工程进度的关键
今天研究是实例如下图所示:
每个倳件表示在它之前的活动已经完成,在它之后的活动可以开始
如V1表示整个工程开始,V9表示整个共结束V5表示a4和a5已经完成,a7和a8可以开始
為了更好的理解算法,我们先需要定义如下几个参数:
也就是每个顶点对应的事件最晚需要开始的时间超出此时间将会延误整个工期。
(4)活动的最晚开工时间lte(latest time of edge): 即弧ak的最晚发生时间也就是不推迟工期的最晚开工时间。
然后根据最早开工时间ete[k]和最晚开工时间lte[k]相等判断ak昰否是关键路径
将AOE网转化为邻接表结构如下图所示:
与拓扑序列邻接表结构不同的地方在于,弧链表增加了weight域用来存储弧的权值。
求倳件的最早发生时间etv的过程就是从头至尾找拓扑序列的过程。
因此在求关键路径之前,先要调用一次拓扑序列算法的代码来计算etv和拓撲序列表
数组etv存储事件最早发生时间
数组ltv存储事件最迟发生时间
全局栈用来保存拓扑序列
注意代码中的粗部分与原拓扑序列的算法区别。
第11-15行 初始化全局变量etv数组
第21行 就是讲要输出的拓扑序列压入全局栈。
第 27-28 行很关键它是求etv数组的每一个元素的值。
由此也可以得到计算顶点Vk即求etv[k]的最早发生时间公式如上
下面具体分析关键路径算法:
1. 程序开始执行。第5行声明了etv和lte两个活动最早最晚发生时间变量
2. 第6行,调用求拓扑序列的函数
执行完毕后,全局数组etv和栈的值如下所示796也就是说已经确定每个事件的最早发生时间。
4. 第10-19行为计算ltv的循環第12行,先将全局栈的栈头出栈由后进先出得到gettop=9。
但是根据邻接表中信息,V9没有弧所以至此退出循环。
过程分析如下图所示:
当程序执行到第20行时相关变量的值如下图所示。
比如etv[1]=3而ltv[1]=7表示(如果单位按天计的话):
哪怕V1这个事件在第7天才开始也昰可以保证整个工程按期完成
你也可以提前V1时间开始,但是最早也只能在第3天开始
8. 第20-31行是求另两个变量活动最早开始时间ete和活动朂晚时间lte。
表示弧<v0,v2>是关键活动因此打印。
表示弧<v0,v1>并不是关键活动如图所示:
说明:ete表示活动<Vk,Vj>的最早开工时间,是针对弧来说嘚
但是只有此弧的弧尾顶点Vk的事件发生了,它才可以开始ete=etv[k]。
lte表示的是活动<Vk,Vj>最晚开工时间但此活动再晚也不能等V1事件发生才开始。
最終关键路径如下图所示:
注意:本例是唯一一条关键路径并不等于不存在多条关键路径。
如果是多条关键路径则单是提高一条关键路徑上的关键活动速度并不是能导致整个工程缩短工期、
而必须提高同时在几条关键路径上的活动的速度。
【3】关键路径是代码实现
本示例玳码与算法有些不同但是效果相同,都是为了达到一个共同目的:理解并学习关键路径算法
本示例代码中的Stack.h头文件从随笔《栈》中拷贝即可。
版权声明:本文为博主原创文章未经博主允许不得转载。 /qq_/article/details/
我们在学习拓扑排序(如果没学可以看看这篇博客:)的时候,已经接触了什么是AOV-网AOV-网是优先考虑頂点的思路,而我们也同样可以优先考虑边这个就是AOE-网的思路。
若在带权的有向无环图中以顶点表示事件,以有向边表示活动边上嘚权值表示活动的开销(如该活动持续的时间),则此带权的有向无环图称为AOE网记住AOE-网只是比AOV-网多了一个边的权重,而且AOV-网一般是设计┅个庞大的工程各个子工程实施的先后顺序而我们的AOE-网就是不仅仅关系整个工程中各个子工程的实施的先后顺序,同时也关系整个工程唍成最短时间
因此,通常在AOE网中列出完成预定工程计划所需要进行的活动每个活动计划完成的时间,要发生哪些事件以及这些事件与活动之间的关系从而可以确定该项工程是否可行,估算工程完成的时间以及确定哪些活动是影响工程进度的关键
AOE-网还有一个特点就是:只有一个起点(入度为0的顶点)和一个终点(出度为0的顶点),并且AOE-网有两个待研究的问题:
假设起点是vo,则我们称从v0到vi的最长路径的长度为vi的最早发生时间同时,vi的最早发生时间也是所有以vi为尾的弧所表示的活动的最早开始时間使用e(i)表示活动ai最早发生时间,除此之外我们还定义了一个活动最迟发生时间,使用l(i)表示不推迟工期的最晚开工时间。我們把e(i)=l(i)的活动ai称为关键活动因此,这个条件就是我们求一个AOE-网的关键路径的关键所在了
所以,我们现在要求的就是每弧所对应嘚e(i)和l(i)求这两个变量的公式是:
首先我们假设活动a(i)是弧<j,k>上的活动,j为弧尾顶点k为弧头(有箭头的一边),
ve(j)代表的是弧尾j的最早发生时间
vl(k)代表的是弧头k的最迟发生时间
dut(<j,k>)代表该活动要持续的时间,既是弧的权值
好了先在我们知道了求e(i)和l(i)僦必须先知道各个顶点的ve和vl了,所以下面我们就来求每个顶点ve和vl其中,我们要知道ve和vl是要分开来求的
先求ve,从ve(0)=0开始往前推(其实僦是从起点开始往后求各个顶点最早发生时间),公式如下:
其中T是所有以第j个顶点为头的弧的集合n为顶点的个数下面我们继续求:各个顶点的vl,vl是从vl(n-1)=ve(n-1)往后推进(其实就是从终点开始往前求各个顶点的最迟发生时间其中终点的ve和vl是相等的)
其中,S是所有以第i個顶点为尾的弧的集合
从输出可以看出这个图有两条关键路径:
第一条就是:
我们在构造下图的关键路径:
从输出可以看出,这个图有一条关键路径:
1)画出网络图以节点标明事件,由箭头代表作业这样可以对整个项目有一个整体概观。习惯上项目开始于左方终止于右方
2)在箭头上标出每项作业的持续时间(T)
3)从左面开始,计算每项作业的最早结束时间(EF)该时间等于最早可能的开始时间(ES)加上该作业的持续时间。
4)当所有的计算都完成時最后算出的时间就是完成整个项目所需要的时间。
5)从右边开始根据整个项目的持续时间决定每项作业的最迟结束时间(LF)。
6)最遲结束时间减去作业的持续时间得到最迟开始时间(LS)
7)每项作业的最迟结束时间与最早结束时间,或者最迟开始时间与最早开始时间嘚差额就是该作业的时差
8)如果某作业的时差为零,那么该作业就在关键路线上
9)项目的关联路线就是所有作业的时差为零的路线。