图论篇5——关键路径

本文介绍了AOE网(Activity On Edge Network)的概念,它是一种以顶点表示事件、边表示活动并附有权值的有向图。关键路径是AOE网中最长的路径,代表工程的最短完成时间。文章详细讲解了如何通过计算最早开始时间(ETE)、最晚开始时间(LTE)、最早发生时间(ETV)和最晚发生时间(LTV)来找到关键路径,并给出了算法描述及示例。
摘要由CSDN通过智能技术生成

引入

AOE网和AOV网

  上一篇的拓扑排序中提到了AOV网(Activity On Vertex Network),与之相对应的是AOE网(Activity on edge network),即边表示活动的网。

  AOV用顶点表示活动的网,描述活动之间的制约关系。

  AOE是带权值的有向图,以顶点表示事件,以边表示活动边上的权值表示活动的开销(如项目工期)AOE 是建立在子过程之间的制约关系没有矛盾的基础之上,再来分析整个过程需要的开销。所以如果给定AOV网中各顶点活动所需要的时间,则可以转换为AOE网,较为简单的方法就是把每个顶点都拆分成两个顶点,分别表示活动的起点和终点

事件和活动

  把上图转换成一般的AOE图如下

  “活动”表示学习课程的过程,而“事件”表示的是一个或者说一种状态(自己的理解),开始和完成活动是一个事件,比如:V4表示学完C语言。而这个事件同时也代表这前面的课程都已经学完了,可以开始学后面的课程了。

关键路径

  AOE一般用来估算工程的完成时间。AOE表示工程的流程,把没有入边的称为始点或者点,没有出边的顶点称为终点或者汇点。一般情况下,AOE只有一个源点一个汇点。但上面用的例图就不止一个,如果碰到这种情况,就可以再加一个“超级源(终)点”,连接所有入(出)度为0的点(不加也不会影响最后的答案)。

关键路径:从源点到汇点具有最长路径强调:就是AOE网中权值和最大的路径),在关键路径上的活动叫关键活动。但为什么是最大长度呢?

  关键路径是AOE网中的最长路径,也是整个工程的最短完成时间,如何理解此处的“最长”和“最短”呢?比如我们想要把“算法设计分析”学完,那么需要的时间就是$max(A1,A2)+(A4)+(A7) = 105days$,那么这105days是最长路径,也是整个工程的最短完成时间,如果我们试图缩短学习的时间,那么缩短“C语言”课程的学习时间显然是没有用的。只有缩短关键路径上的关键活动时间才可以减少整个项目的时间。比如让“离散数学”的时间缩短为30days,则总时间就会减少为90days。

来看四个定义(活动是一个过程,用“开始”,事件是一个时间点,用“发生”):

活动的最早开始时间 ETE(earliest time of edge):所有前导活动都完成,可以开始的时间。

活动的最晚开始时间 LTE(latest time of edge):不推迟工期的最晚开工时间。

事件的最早发生时间 ETV(earliest time of vertex):可以等价理解为旧活动的最早结束时间 或 新活动的最早开始时间

事件的最晚发生时间 LTV(latest time of vertex):可以等价理解为就活动的最晚结束时间 或 新活动的最晚开始时间

  举例说明一下,“数据结构”课程的活动最早开始时间就是“离散数学”学完,45days。对于“C语言”课程来说,需要30days,而“离散数学”需要45days,那么“C语言”在“离散数学”开始后的15days,再开始也不会延迟整个学习的时间,这就是活动最晚开始时间

算法描述

  我们把关键路径上的活动称作关键活动,那么对于关键活动来说,它们是不允许拖延的,因此这些活动的最早开始时间必须是等于最晚开始时间,同理,把关键路径上的事件称作关键事件,他们的最早发生时间也是等于最晚发生时间因此可以设置数组$E$和$L$,其中$E[r]$和$L[r]$分别表示活动$A_r$的最早开始时间和最晚开始时间,于是,我们只要求出这两个数组就可以通过判断$E[r]==L[r]$来确定$r$是否为关键活动了。

  再引入两个新的数组$VE$和$VL$,其中$VE[i]$和$VL[i]$分别表示事件$i$的最早发生时间最晚发生时间。

  举个例子,看下图

  我们可以得出以下四个等式

1.事件$V_i$的最早发生时间就是活动$A_r$的最早开始时间,即$E[r]=VE[i]$

2.事件$V_j$的最早发生时间就是活动$A_r$的最早完成时间,即$E[r]+length[r]=VE[j]$

3.事件$V_i$的最晚发生时间就是活动$A_r$的最晚开始时间,即$VL[i]=L[r]$

4.事件$V_j$的最晚发生时间就是活动$A_r$的最晚开始时间$+$活动$A_r$的权值,即$VL[j]=L[r]+length[r]$

把1、2合起来就是$VE[j]=VE[i]+length[r]$,把3、4合起来就是$VL[i]=VL[j]-length[r]$,这样我们就可以先要求出$VE$和$VL$这两个数组,然后通过上面的等式得到$E$和$L$数组。

求VE数组

根据$VE[j]=VE[i]+length[r]$,假设我们已知了事件$V_{i1},...V_{ik}$的最早发生时间$VE[i_{1}]....VE[i_{k}]$,那么事件$V_j$的最早发生时间就是$max(VE[i_{1}]+length[r_{1}],...,VE[i_{k}]+length[r_{k}])$,取最大值就是所有能到达$V_j$的活动中最后一个完成的时间,因为只有它们都完成后,$V_j$才算“激活”。

也就是有这样一个式子$$VE\left[ j\right] =\max \left( VE\left[ i_{p}\right] +length\left[ r_{p}\right] \right),\ p=1,2,...,k$$

如果要计算出$VE[j]$的正确值,就必须在访问$V_j$之前$VE[i_{1}]....VE[i_{k}]$都已经得到,也就是在访问某个结点的时候保证它的前驱结点都已经访问完毕了,这就需要用到上一篇的拓扑排序了,此部分代码如下:

const int N = 30000;
vector<pair<int, int>>G[N + 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值