一、有向无环图的表达形式
概念:若一个有向图不存在环,则称为有向无环图,简称DAG图
有向无环图是描述含有公共子式的表达式的有效工具
举例子:
-
把各个操作数不重复的拍成一排列,有:abcde
-
标出各个运算符的生效顺序(先后顺序优点出入无所谓
-
按顺序加入运算符,注意:“
分层
”- 第一层:第一个,加入的是(a+b),第二个加入的是(c+d),则第一层为 如下图
2. 第二层:由于第三个需要加入的是乘法,需要用到第一层的(c+d)的结果,所以第三个加入的为第三层
3. 以此类推:
-
从底向上逐层检查同层的运算符是否可以合体
- 可以发现第一层有后面三个都是来自c+d的加号,则可以进行合体操作
- 第二层的后面两个乘号都是来自(c+d)结果和e的结果,因为可以进行合体
二、拓扑排序
2.1AOV网
AOV网概念:若用DAG图表示一个工程,其
顶点表示活动
,用有向边<vi,vj>
表示活动vi必须
先于vj进行的这样一种关系,则将这种有向图称为顶点表示活动的回路
注意:!AOV网一定是一个有向无环图!
2.2拓扑排序
满足以下条件,称为该图的一个拓扑排序:
- 每个顶点出现且只出现一次
- 若顶点A在序列中排在顶点B的前面,则在图中不存在从顶点B到顶点A的路径
若定义为:
- 拓扑排序是对有向无环图丁点的一种排序。
- 它使得若存在一条从顶点A到顶点B的路径,则在排序中顶点B出现在顶点A得后面。
- 每一个AOV网都有一个或多个拓扑排序序列
拓扑排序的实现: - 从AOV网中选择一个没有
前驱(入度为0)
的顶点并输出 - 从网中删除该顶点和所有以它为起始的有向边
- 重复1、2步骤直到当前的AOV网为空 或 当前网中不存在无前驱的顶点为止
2.3逆拓扑排序
逆拓扑排序的实现:
- 从AOV网中选择一个没有
后继(出度为0)
的顶点并输出 - 从网中删除该顶点和所有以它为起始的有向边
- 重复1、2步骤直到当前的AOV网为空 或 当前网中不存在无前驱的顶点为止
2.4重要知识点回顾
三、关键路径
3.1关于AOV与AOE区别:
AOV(vertex):用顶点表示活动
AOE(edge):用边表示活动
3.2什么是AOE
AOE网:在带权有向图中,以顶点表示事件,以边上的权值表示完成该活动的开销(如完成活动所的时间),称之为用边表示活动的网络,简称为AOE
3.3AOE的两个性质:
只有在某顶点所代表的事件发生后,从该顶点出发的各个有向边所代表的活动才能开始
- 只有在“开始”这个事件发生后,才可以发生大鸡蛋和西番茄这两个活动
- 只有在”开始抄了“这个事件发生后,才可以发生
只有在进入某顶点的各有向边所代表的活动都已经结束时,该顶点所代表的事情才能发生
- 只有做完“打鸡蛋”、“切番茄”这个活动后才可以发生“可以炒了”
另外,有些活动是可以并行进行的
- 可以有很多人在打鸡蛋、洗番茄
- 但是“洗番茄“ 和 ”可以切“了这两个是无法并行的,因为只有”洗完番茄“之后才可以进行“可以切”
3.4AOE相关概念性质:
- 从源点到汇点的有向路径可能有多条,所有路径中,具有
最大路径长度的路径
称为关键路径
,而把关键路径上的活动
称为关键活动
- 完成整个工程的
最短时间
就是最短关键路径的长度
,若关键活动不能按时完成,则整个工程的完成时间就会延长
因为“开始炒了”与洗番茄、切番茄是可以并行的,所以只需要4分钟
3.5所有事件的最早发生时ve()
求解步骤:
-
首先按照拓扑排序 排好序
-
ve(源点)=0
-
ve(k)= Max{ve(j)+Weight(vj,vk)}
ve(k)= 是为前驱顶点的最早发生时间+活动的时间(边的权值)翻译中文:最早发生时间是当前结点(vj)的最早发生发生时间 与 当前前驱节点(vk)的活动时间加和,若有两条路径的路径的话,则取最大
举例说明
- v3顶点有可能的是为前驱顶点(v1)的最早发生时间+活动的时间(2),所以ve(3)=2
- v4顶点与其他不同,因为他有两个直接前驱v2、v3:
- v2->v4: v2这个事件最早有可能在v2这个时刻发生为3,发生这个事件之后,还需要2才有可能发生v4=5;
- v2->v3:v2这个事件最早有可能在v3这个时刻发生为4,发生这个事件之后,还需要4才有可能发生v4=6;
- 取最大的为6,所以ve(4)=6
3.6所有事件的最迟发生时间vl()
求解步骤:
-
首先按照逆拓扑排序 排好序
-
vl(汇点) = ve(汇点) ——(ve的汇点:即拓扑排序的最后一个结点,vl的汇点:即逆拓扑排序的第一个结点)
-
vl(k)= Min{vl(j) - Weight(vk,vj)} (vj为vk的任意后继)
vl(k)= 是为后继结点的最迟发生时间 - 活动的时间(边的权值)翻译中文:最迟发生时间是当前结点(vk)的最迟发生发生时间 与 当前后驱节点(vj)的活动时间相减,若有两条路径的路径的话,则取最小
举例说明:
- v5:用v6的最迟发生时间-边的权值
- v4:v4的后继是v6,用v6的最迟发生事件-边的权值=8-2=6
- v2:有两个直接后继(v4、v5),
- v5这个事件必须在7这个事件发生,而在v5之前又必须进行a4=3这个活动,所以v2至少需要在7-4这个时间进行发生为3
- v2:有两个直接后继(v4、v5),v4这个事件必须在6这个事件发生,而在v5之前又必须进行a3=2这个活动,所以v2至少需要在6-2这个时间进行发生为4
3.7所有活动的最早发生时间e()
最早发生时间e():这个活动所对应的狐尾
的所连的事件的最短发生时间,此前已经求过最短发生时间了,所以只需要根据之前的表哥就可以知道最短发生时间ve为多少
3.8所有活动的最迟发生时间e()
所有活动的最迟发生时间=这条弧所指向的这个结点(的最晚发生时间)-这条弧长的权值
举例说明:
- v6这个时间最晚可以在8这个时刻发生,那么a8这个活动总共需要消耗1的时间,所以a8最迟发生时间就需要在8-1=7
- 这个时刻开始a4这个活动,所指向的事件是v5,最迟允许7这个时刻发生,那么a4这个活动需要消耗3这个时间,所以a4最迟发生时间需要在7-3=4这个时候开始
3.9所有活动的时间余量d()
时间剩余量为0的活动代表,是绝对不允许拖延的,若拖延,那么整个活动完成的工期要比8更晚
3.10关键路径的特征
1. 一个图中可能存在多条关键路径,只提高一条关键路径上的关键活动速度并不能缩短整个工程的工期
2.要想缩短整个工程的工期,,只有加快那么包括所有关键路径上的关键活动才能够缩短工期的目的
炒菜是一个关键活动,我们将其压缩为a4=1,那么就可以提前结果
当一个关键活动耗时缩短的时候。。。
若用一分钟完成切番茄这个活动的话,那么完成番茄炒蛋只需要4分钟时间
在进行进一步的压缩,a3=0.5,此时就没办法让你的工程结束了,以前这条关键路径(最大路径长度的路径)已经不在是关键路径,上面需要4时间,下面不需要。
四、重要知识点回顾
事件最早发生时间ve
为前驱顶点的最早发生时间+活动的时间(边的权值),若有两条路径的路径的话,则取最大
事件最迟发生时间vl
当前结点(vk)的最迟发生发生时间 - 当前后驱节点(vj)的活动时间相减,若有两条路径的路径的话,则取最小
活动最早发生时间e()
这个活动所对应的狐尾
的所连的事件的最早发生时间
活动的最迟发生时间l()
这条弧所指向的这个结点(的最晚发生时间)-这条弧长的权值
所有活动的时间余量d()
时间剩余量为0的活动代表,是绝对不允许拖延的,若拖延,那么整个活动完成的工期要比关键路径长度更长、时间更晚
五、例题
题目需要我们求关键路径长度:那么求出最早开始时间即可
- 顶点1:为0
- 顶点2:是由顶点1过来的,所以为5
- 顶点5:
- 有三条路径可以到达顶点6
- 1->2->5= 5+5=10
- 1->3->4->5= 6+3+3=12
- 1->3->5= 6+6=12
- 去最大值为12
- 依次类推,算出最后一个顶点为21,那么我们的关键路径长度为21
拓展:求关键路径
求关键路径步骤:还需要算出最晚开始时间,当最早开始时间=最晚开始时间的部分,就是关键路径
求最晚开始时间:与其相连接的顶点的最晚发生时间-边权值(取最小值)
-
顶点10:最后一个顶点的最晚开始时间=最早开始时间
-
顶点9:最早开始时间-边界值:21-2=19
-
顶点4:有三条路径
-
10<-9<-8<-4 : 21-2-5-1=13
-
10<-9<-7<-4 : 21-2-4=14
-
10<-6<-5<-4 : 21-4-4-3=14
-
以上的算法是错误的
-
正确的应该是首先得出有三条路径:5、8、7
-
5的最晚开始时间12,那么需要通过12-3=9
-
8的最晚开始时间17,那么需要通过17-4=13
-
7的最晚开始时间14,那么需要通过17-4=13
-
取最小值,所以顶点4的最早发生时间为13
若最晚开始时间的第一个顶点不是0的话,则说明整个工期是可以提前的
-