SlideShare a Scribd company logo
关键路径 Critical Paths

    刚对付了难缠的 AOV-网,又要来和它的破哥们儿 AOE-网斗志斗勇了。通缉它!
AOE 网—Activity On Edge
  顶点----事件
  边------活动
  权------活动持续的时间
事件 i 发生后,    其后继活动 a(i,*)都可以开始;只有所有先导活动 a(*,j)
都结束后,事件 j 才发生。




教材 P183 对 AOE-网的解释很清晰。




   1
问题:a) 整个工程完工需要多长时间? b) 哪些活动影响工程的进度?或求关键路径。

请注意看一下上面的那些相关定义和名词解释,一定要看懂弄明白。
关键路径就是路径长度最长的路径。          你可能听过短板效应,       这里其实也是这种效应的变形吧,
只不过取决于最长的那些事情。      总有一些东西是关键。         下面的表示可能和教材稍微有一点差
别。不过,应该更容易理解。
 事件(顶点) i: 最早发生时间 ve(i),最晚发生时间 vl(i);
 活动(边) a(i,j):最早开始时间 e(i,j),最晚开始时间 l(i,j)。
于是,整个工程完工的时间就是终点的最早发生时间;关键路径就是路径长度最长的路径。
弄明白下面的几个关系:
                     1、关键活动就是 e(i)=l(i)的活动。
                     2、活动的最早发生时间 e(i,j)与事件的最早发生时间
                     ve(i)有关,且 e(i, j ) = ve(i), 。想也能想明白,事件最早什
                  么时候开始当然取决于事件最早什么时候开始了,不然它
                  自己开始个头头啊。
3、活动 a(i,j)的最晚开始时间 l(i,j)取决于 a(i,j)所连接的前后两个活动中的后一个活
动的最晚开始时间,以及这个活动能够持续的时间,即 l (i, j ) = vl ( j ) − a(i, j ) 。就是后面的课代
表一拖再拖最迟能够在周四收作业, 你写数据结构作业还有有两天,    当然你最晚要在周二开
始写啦,当然如果不写那就是另外的事情了。
上面的只是它们的关系,如何求才 ve(i)和 vl(i)才是最重要的东东。
算法:

1、求关键路径的第一步是计算出 AOE-网的拓扑有序序列,逆拓扑有序自然也就出来了。没
有了拓扑序列的技术支持,有可能做对,但是很悬。为了那将要来之不易的分数,好好的把
拓扑排序序列列出来吧。




2、从源点 ve(0)=0 开始按照拓扑有序求其余各个顶点的最早发生时间 ve(i)。
  计算 ve(j):
   ⎧ve (1) = 0,                       ,其中*为任意前驱事件;
   ⎨
   ⎩ve ( j ) = max{ve (*) + a (*, j)}
即求顶点 j(上图中后一个顶点) 的 ve(j),就是将所有指向这个顶点的边中,从起点计算
权值之和,ve(j)去其中最大的。
重复一下,从源点开始直至汇点,依次按照拓扑有序计算。
3、从汇点 vn 出发,令这个顶点的最早开始时间 ve(n-1)和最晚开始时间 vl(n-1)相同(本
来就一样的)   。然后按照逆拓扑有序进行往前推导。
  计算 vl(i):
         ⎧vl (n ) = ve (n ),               其中*为任意后继事件;
         ⎨
         ⎩vl (i ) = min{vl (*) − a (i ,*)}
   求顶点 i 的 vl(i)就是将所有从这个顶点出发边中,用紧跟的顶点的最晚开始时间减去
   权值,选择最小的即可。因为是按照逆拓扑有序进行,因此后面的顶点的最晚时间是已
   经被算出的。

    2
4、根据各个顶点的 ve 和 vl 值,求出每条弧的最早开始时间和最晚开始时间,若某条
     弧满足两个相等,就是关键活动。最终的关键活动可能有多条路线。
     计算 e(i,j)和 l(i,j):
           e (i , j ) = ve (i ),              ,工程总用时 ve(n),关键活动是 e(i,j)=l(i,j)的活动 a(i,j)。
           l (i , j ) = vl ( j ) − a (i , j )
说明:
  10. 若只求工程的总用时只要进行步骤(a)-(b)即可求得。
  20. 如何理解计算 ve(j)和 vl(i)的公式:
  事件 j 在所有前驱活动都完成后发生,所以其最早 a(*,j) j       i a(i,*)
  发生时间 ve(j) = max{ve(*)+a(*,j)},即取决于最慢的
  前驱活动。另一方面,事件 i 发生后所有后继活动都可以开始了,所以其最晚发生时间
  vl(i) = min{vl(*)-a(i,*)},即不耽误最慢的后继活动。
例:某工程的 AOE 网如下,求 1) 整个工程完工需要多长时间,2) 关键路径。说明:图中
的虚线仅表示事件的先后关系,不代表具体活动。
                                1                5
                        2                5               7       2
                6                   1            3
                    4                                                 9
            1               3                        8       4
                5                                4
                                1
                        4                    6
分析:按照拓扑有序排列顶点,然后“从前往后”计算事件的最早发生时间得到总时间,   再
“从后往前”   计算事件的最晚发生时间,最后计算活动的最早和最晚开始时间得到关键活动
和关键路径。
表 7.2 关键路径
事件    最早发生时间 ve                     最晚发生时间 vl                活动           最早开始时间   最晚开始时间
                                                                          e        l
v1    0                             0                        a(1,2)       0        0
v2    6                             6                        a(1,3)       0        2
v3    4                             6                        a(1,4)       0        1
v4    5                             6                        a(2,5)       6        6
v5    7                             7                        a(3,5)       4        6
v6    7                             7                        a(4,6)       5        6
v7    12                            13                       a(5,6)       7        7
v8    11                            11                       a(5,7)       7        8
v9    15                            15                       a(5,8)       7        8
                                                             a(6,8)       7        7
                                                             a(7,9)       12       13
                                                             a(8,9)       11       11
所以,1) 工程完工需要时间 15,2) 关键路径是 1�2�5�6�8�9。
  同样,教材 P186 的例子也非常好,习题集 7.10 可以认真做一下,题目出的比较好。




     从应试的角度看,求关键路径重要的是能够正确的画出上面的表格。但是算法可以更好
     3
的理解里面的细节。


Status TopologicalOrder(ALGraph G, Stack &T)
{FindInDegree(G, indegree);    //对各顶点求入度 indegree
 InitStack(S);              //建零入度顶点栈 S
 将入度为 0 的顶点入 S 栈;
 InitStack(T); count = 0;
 ve[0..G.vexnum - 1] = 0;                  // 初始化
While (! StackEmpty(S))
 { Pop(S, j); Push(T,j); ++count; //j 号顶点入 T 栈并计数
    for(p=G.vertices[j].firstarc;p;p=p->nextarc)
    {k = p->adjvex;           // 对 j 号顶点的每个邻接点的入度减 1
     if(--indegree[k]==0)Push(S, k); //若入度减为 0,则入栈
     if(ve[j]+*(p->info)>ve[k])ve[k]=ve[j]+*(p->info);
       }// *(p->info)= dut(<j,k>)
  }// while
  if(count<G.vexnum) return ERROR; //该有向网有回路
  else return OK;
}// TopologicalOrder
Status CriticalPath(ALGraph G)
{ //G 为有向网,输出 G 的各项关键活动
  if(!TopologicalOrder(G,T)) return ERROR;
  vl[0..G.vexnum-1]=ve[0..G.vexnum-1];
                            //初始化顶点事件的最迟发生时间
 while (! StackEmpty(T))            //按拓扑逆序求各顶点的 v1 值
  for(Pop(T,j),p=G.vertices[j].firstarc; p; p=p->nextarc)
  {k=p->adjvex;        dut = * (p->info);        // dut<j,k>
    if(vl[k]-dut<v1[j]) vl[j] = vl[k]-dut;
  }// for
for(j=0;j<G.vexnum; ++j)              // 求 ee,e1 和关键活动
    for(p=G.vertices[j].firstarc; p; p = p->nextarc)
      { k = p->adjvex; dut = * (p->info) ;
         ee=ve[j]; el=vl[k]-dut; tag=(ee==e1)? '*' : '' ;
        printf ( j,k, dut, ee, el, tag);       // 输出关键活动
     }
}// CriticalPath




  4

More Related Content

Viewers also liked

数据结构复习笔记 图的邻接表存储表示及重要的基本操作
数据结构复习笔记 图的邻接表存储表示及重要的基本操作数据结构复习笔记 图的邻接表存储表示及重要的基本操作
数据结构复习笔记 图的邻接表存储表示及重要的基本操作mengyingchina
 
数据结构复习笔记 静态链表
数据结构复习笔记 静态链表数据结构复习笔记 静态链表
数据结构复习笔记 静态链表
mengyingchina
 
数据结构复习笔记 拓扑排序Topological+sort
数据结构复习笔记 拓扑排序Topological+sort数据结构复习笔记 拓扑排序Topological+sort
数据结构复习笔记 拓扑排序Topological+sortmengyingchina
 
哈佛幸福课[升级版]
哈佛幸福课[升级版]哈佛幸福课[升级版]
哈佛幸福课[升级版]
mengyingchina
 
文献综述
文献综述文献综述
文献综述
mengyingchina
 
Microlivestock and livelihood security in Hilly regions of India
Microlivestock and livelihood security in Hilly regions of IndiaMicrolivestock and livelihood security in Hilly regions of India
Microlivestock and livelihood security in Hilly regions of IndiaDr Devesh Thakur
 
Quiz feb 2013 vet palampur h.p.
Quiz feb 2013 vet palampur h.p.Quiz feb 2013 vet palampur h.p.
Quiz feb 2013 vet palampur h.p.Dr Devesh Thakur
 
Disaster Preparedness Guide
Disaster Preparedness GuideDisaster Preparedness Guide
Disaster Preparedness Guide
cmgreo
 

Viewers also liked (9)

数据结构复习笔记 图的邻接表存储表示及重要的基本操作
数据结构复习笔记 图的邻接表存储表示及重要的基本操作数据结构复习笔记 图的邻接表存储表示及重要的基本操作
数据结构复习笔记 图的邻接表存储表示及重要的基本操作
 
数据结构复习笔记 静态链表
数据结构复习笔记 静态链表数据结构复习笔记 静态链表
数据结构复习笔记 静态链表
 
数据结构复习笔记 拓扑排序Topological+sort
数据结构复习笔记 拓扑排序Topological+sort数据结构复习笔记 拓扑排序Topological+sort
数据结构复习笔记 拓扑排序Topological+sort
 
哈佛幸福课[升级版]
哈佛幸福课[升级版]哈佛幸福课[升级版]
哈佛幸福课[升级版]
 
文献综述
文献综述文献综述
文献综述
 
Microlivestock and livelihood security in Hilly regions of India
Microlivestock and livelihood security in Hilly regions of IndiaMicrolivestock and livelihood security in Hilly regions of India
Microlivestock and livelihood security in Hilly regions of India
 
Quiz feb 2013 vet palampur h.p.
Quiz feb 2013 vet palampur h.p.Quiz feb 2013 vet palampur h.p.
Quiz feb 2013 vet palampur h.p.
 
World vet quiz 2013
World vet quiz 2013World vet quiz 2013
World vet quiz 2013
 
Disaster Preparedness Guide
Disaster Preparedness GuideDisaster Preparedness Guide
Disaster Preparedness Guide
 

数据结构复习笔记 关键路径+Critical+paths

  • 1. 关键路径 Critical Paths 刚对付了难缠的 AOV-网,又要来和它的破哥们儿 AOE-网斗志斗勇了。通缉它! AOE 网—Activity On Edge 顶点----事件 边------活动 权------活动持续的时间 事件 i 发生后, 其后继活动 a(i,*)都可以开始;只有所有先导活动 a(*,j) 都结束后,事件 j 才发生。 教材 P183 对 AOE-网的解释很清晰。 1
  • 2. 问题:a) 整个工程完工需要多长时间? b) 哪些活动影响工程的进度?或求关键路径。 请注意看一下上面的那些相关定义和名词解释,一定要看懂弄明白。 关键路径就是路径长度最长的路径。 你可能听过短板效应, 这里其实也是这种效应的变形吧, 只不过取决于最长的那些事情。 总有一些东西是关键。 下面的表示可能和教材稍微有一点差 别。不过,应该更容易理解。 事件(顶点) i: 最早发生时间 ve(i),最晚发生时间 vl(i); 活动(边) a(i,j):最早开始时间 e(i,j),最晚开始时间 l(i,j)。 于是,整个工程完工的时间就是终点的最早发生时间;关键路径就是路径长度最长的路径。 弄明白下面的几个关系: 1、关键活动就是 e(i)=l(i)的活动。 2、活动的最早发生时间 e(i,j)与事件的最早发生时间 ve(i)有关,且 e(i, j ) = ve(i), 。想也能想明白,事件最早什 么时候开始当然取决于事件最早什么时候开始了,不然它 自己开始个头头啊。 3、活动 a(i,j)的最晚开始时间 l(i,j)取决于 a(i,j)所连接的前后两个活动中的后一个活 动的最晚开始时间,以及这个活动能够持续的时间,即 l (i, j ) = vl ( j ) − a(i, j ) 。就是后面的课代 表一拖再拖最迟能够在周四收作业, 你写数据结构作业还有有两天, 当然你最晚要在周二开 始写啦,当然如果不写那就是另外的事情了。 上面的只是它们的关系,如何求才 ve(i)和 vl(i)才是最重要的东东。 算法: 1、求关键路径的第一步是计算出 AOE-网的拓扑有序序列,逆拓扑有序自然也就出来了。没 有了拓扑序列的技术支持,有可能做对,但是很悬。为了那将要来之不易的分数,好好的把 拓扑排序序列列出来吧。 2、从源点 ve(0)=0 开始按照拓扑有序求其余各个顶点的最早发生时间 ve(i)。 计算 ve(j): ⎧ve (1) = 0, ,其中*为任意前驱事件; ⎨ ⎩ve ( j ) = max{ve (*) + a (*, j)} 即求顶点 j(上图中后一个顶点) 的 ve(j),就是将所有指向这个顶点的边中,从起点计算 权值之和,ve(j)去其中最大的。 重复一下,从源点开始直至汇点,依次按照拓扑有序计算。 3、从汇点 vn 出发,令这个顶点的最早开始时间 ve(n-1)和最晚开始时间 vl(n-1)相同(本 来就一样的) 。然后按照逆拓扑有序进行往前推导。 计算 vl(i): ⎧vl (n ) = ve (n ), 其中*为任意后继事件; ⎨ ⎩vl (i ) = min{vl (*) − a (i ,*)} 求顶点 i 的 vl(i)就是将所有从这个顶点出发边中,用紧跟的顶点的最晚开始时间减去 权值,选择最小的即可。因为是按照逆拓扑有序进行,因此后面的顶点的最晚时间是已 经被算出的。 2
  • 3. 4、根据各个顶点的 ve 和 vl 值,求出每条弧的最早开始时间和最晚开始时间,若某条 弧满足两个相等,就是关键活动。最终的关键活动可能有多条路线。 计算 e(i,j)和 l(i,j): e (i , j ) = ve (i ), ,工程总用时 ve(n),关键活动是 e(i,j)=l(i,j)的活动 a(i,j)。 l (i , j ) = vl ( j ) − a (i , j ) 说明: 10. 若只求工程的总用时只要进行步骤(a)-(b)即可求得。 20. 如何理解计算 ve(j)和 vl(i)的公式: 事件 j 在所有前驱活动都完成后发生,所以其最早 a(*,j) j i a(i,*) 发生时间 ve(j) = max{ve(*)+a(*,j)},即取决于最慢的 前驱活动。另一方面,事件 i 发生后所有后继活动都可以开始了,所以其最晚发生时间 vl(i) = min{vl(*)-a(i,*)},即不耽误最慢的后继活动。 例:某工程的 AOE 网如下,求 1) 整个工程完工需要多长时间,2) 关键路径。说明:图中 的虚线仅表示事件的先后关系,不代表具体活动。 1 5 2 5 7 2 6 1 3 4 9 1 3 8 4 5 4 1 4 6 分析:按照拓扑有序排列顶点,然后“从前往后”计算事件的最早发生时间得到总时间, 再 “从后往前” 计算事件的最晚发生时间,最后计算活动的最早和最晚开始时间得到关键活动 和关键路径。 表 7.2 关键路径 事件 最早发生时间 ve 最晚发生时间 vl 活动 最早开始时间 最晚开始时间 e l v1 0 0 a(1,2) 0 0 v2 6 6 a(1,3) 0 2 v3 4 6 a(1,4) 0 1 v4 5 6 a(2,5) 6 6 v5 7 7 a(3,5) 4 6 v6 7 7 a(4,6) 5 6 v7 12 13 a(5,6) 7 7 v8 11 11 a(5,7) 7 8 v9 15 15 a(5,8) 7 8 a(6,8) 7 7 a(7,9) 12 13 a(8,9) 11 11 所以,1) 工程完工需要时间 15,2) 关键路径是 1�2�5�6�8�9。 同样,教材 P186 的例子也非常好,习题集 7.10 可以认真做一下,题目出的比较好。 从应试的角度看,求关键路径重要的是能够正确的画出上面的表格。但是算法可以更好 3
  • 4. 的理解里面的细节。 Status TopologicalOrder(ALGraph G, Stack &T) {FindInDegree(G, indegree); //对各顶点求入度 indegree InitStack(S); //建零入度顶点栈 S 将入度为 0 的顶点入 S 栈; InitStack(T); count = 0; ve[0..G.vexnum - 1] = 0; // 初始化 While (! StackEmpty(S)) { Pop(S, j); Push(T,j); ++count; //j 号顶点入 T 栈并计数 for(p=G.vertices[j].firstarc;p;p=p->nextarc) {k = p->adjvex; // 对 j 号顶点的每个邻接点的入度减 1 if(--indegree[k]==0)Push(S, k); //若入度减为 0,则入栈 if(ve[j]+*(p->info)>ve[k])ve[k]=ve[j]+*(p->info); }// *(p->info)= dut(<j,k>) }// while if(count<G.vexnum) return ERROR; //该有向网有回路 else return OK; }// TopologicalOrder Status CriticalPath(ALGraph G) { //G 为有向网,输出 G 的各项关键活动 if(!TopologicalOrder(G,T)) return ERROR; vl[0..G.vexnum-1]=ve[0..G.vexnum-1]; //初始化顶点事件的最迟发生时间 while (! StackEmpty(T)) //按拓扑逆序求各顶点的 v1 值 for(Pop(T,j),p=G.vertices[j].firstarc; p; p=p->nextarc) {k=p->adjvex; dut = * (p->info); // dut<j,k> if(vl[k]-dut<v1[j]) vl[j] = vl[k]-dut; }// for for(j=0;j<G.vexnum; ++j) // 求 ee,e1 和关键活动 for(p=G.vertices[j].firstarc; p; p = p->nextarc) { k = p->adjvex; dut = * (p->info) ; ee=ve[j]; el=vl[k]-dut; tag=(ee==e1)? '*' : '' ; printf ( j,k, dut, ee, el, tag); // 输出关键活动 } }// CriticalPath 4