拓扑排序的意义是解决工程的顺序进行问题,但有时我们也需要解决工程完成需要的最短时间问题。

AOV网和AOE网:

AOE(Activity On Edge)网:顶点表示事件,弧表示活动,弧上权值表示活动所需时间

网中没有入边的顶点称为始点或源点,没有出边的顶点称为终点或汇点

在AOE网中,只有一个顶点代表的事件发生后,从该顶点出发的各个弧所代表的活动才能开始,只有以弧头关联一个顶点的各个弧所代表的活动都已结束,该顶点所代表的事件才能发生。

一项工程可以由若干个子工程活动组成。用AOV网表示这项工程所关心的是各子工程之间的优先次序,即所得到得拓扑有序序列;而用AOE网表示这项工程所关心的是完成整个工程至少需要多少时间,哪些子工程是影响这项工程进度的关键活动,如何加快整个工程的进度等问题。

由于在AOE网中某些活动可以并行进行,所以完成工程的最短时间是从源点到汇点路径的最大长度(指路径上各活动持续时间之和最大,而不是路径上弧的数目最多)。把从源点到汇点路径长度最大的路径称作关键路径(critical path),关键路径上的活动称作关键活动。关键活动的长度是整个工程的最短工期,加快关键活动的完成是加快工程进度缩短工期地关键。

也就是说只有缩短关键路径上的关键活动时间才可以减少整个工期长度

关键路径算法:

首先定义几个参数:

事件的最早发生时间ve(vertex earliest):即顶点V的最早发生时间

事件的最晚发生时间vl(vertex latest):即顶点V的最晚发生时间

活动的最早开始时间e:即弧的最早开始时间

活动的最晚开始时间l:即弧的最晚开始时间,也就是不推迟工期的最晚开始时间

判断关键活动看是否有: e(i)=l(i)


我们假设活动a(i)是弧<j,k>上的活动,

j为弧尾顶点,k为弧头(有箭头的一边)

ve(j)代表的是弧尾j的最早发生时间,vl(k)代表的是弧头k的最迟发生时间

dut(<j,k>)代表该活动要持续的时间,既是弧的权值





1.从源点开始每个活动所需要最长的时间就是事件最早开始时间ve:

ve(j)=Max{ve{i}+dut(<i,j>)};

如v1,只有v0指向它,那么最早开始时间就是3;相对于v3,v0->v2->v3=4+8=12,v0->v1->v3=3+5=8,两者比较,前者大,两者取大的,故12为最早开始时间,依次类推。

2.从汇点开始逆向拓扑排序,事件最晚开始时间vl:

vl(i)=Min{vl(j)-dut(<i,j>)};

从右边倒推,可以求的最迟开始时间,如v9为27,以v8为例,v8->v9 倒推 27-3=24 所以v8最迟开始时间为24;

v4为例,v4->v7->v8->v9 倒推27-3-5-4=15,v4->v6->v9 倒推 27-2-9=16,两者取小的,所以v4的最迟开始时间为15。


我们现在要求的就是每弧所对应的e(i)和l(i),求这两个变量的公式是:

e(i)=ve(j)
l(i)=vl(k)-dut(<j,k>)


知道了一切所需的条件之后我们可以开始着手于算法的实现了:



建立一个邻接表。

求事件最早发生时间ve就是从头至尾找拓扑序列的过程,因此在求关键路径之前需要先调用一次拓扑序列算法来计算ve和拓扑序列列表,为此先声明几个全局变量:

int *ve,*vl;     //事件最早发生时间和最晚发生时间数组
int *stack2;    //用于存储拓扑序列的栈
int top2;       //用于stack2的栈 

stack2用来存储拓扑序列,在关键路径时用到

以下是改进后的拓扑排序:

Status TopologicalSort(GraphAdjList G)
{EdgeNode *e;int i,k,gettop;int top=0;         //栈顶下标,空栈为0 int count=0;        //统计输出的顶点数int *stack;                                       //该类型的栈 stack=(int *)malloc(G->numVertexes*sizeof(int)); //该条代码要注意 for(i=0;i<G->numVertexes;i++)if(G->adjList[i].in==0)   //入度为0则入栈 stack[++top]=i;top2=0;etv=(int *)malloc(G->numVertexes*sizeof(int));for(i=0;i<G->numVertexes;i++)ve[i]=0;    //初始化      stack2=(int *)malloc(G->numVertexes*sizeof(int)); //初始化 while(top!=0){gettop=stack[top--];count++;stack2[++top2]=gettop;    //将弹出的顶点序号压入拓扑序列的栈 for(e=G->adjList[gettop].firstedge;e;e=e->next)   {//对此顶点的弧表进行遍历k=e->adjvex;--G->adjList[k].in;    //将与该顶点有连线的其他顶点入度减去1 if(!G->adjList[k].in)   //其他顶点入度为0时也入栈 stack[++top]=k;/*重要代码*/   if((ve[gettop]+e->weight)>ve[k])  //求各顶点事件的最早发生时间!! etv[k]=etv[gettop]+e->weight; } } if(count<G->numVertexes)return ERROR;elsereturn OK;
} 

需要注意的是:

全局变量ve,vl的int *类型,以及int *stack2的类型

第8 14 17行代码申请动态存储空间堆栈的含义

19-36行的循环中,重要if语句

关键路径算法代码:

void CriticalPath(GraphAdjList G)
{EdgeNode *e;int i,gettop,k,j;int ear,last;      //活动最早,最晚开始时间  TopologicalSort(G);l=(int *)malloc(G->numVertexes*sizeof(int));for(i=0;i<G->numVertexes;i++)vl[i]=ve[G->numVertexes];       //初始化事件最晚时间while(top2!=0){gettop=stack2[top2--];for(e=G->adjList[gettop].firstedge;e;e=e->next)   {//求各顶点事件的最晚发生时间vlk=e->adjvex;if(vl[k]-e->weight<vl[gettop])vl[gettop]=vl[k]-e->weight;}}for(j=0;j<G->numVertexes;j++) //对每个顶点循环 {for(e=G->adjList[j].firstedge;e;e=e->next) //对每个弧表循环 {k=e->adjvex;ear=ve[j];last=vl[k]-e->weight;if(ear==last)printf("<V%d,V%d> length:%d",G->adjList[j].data,G->adjList[k].data,e->weight);}}
} 

第20行循环代码内是判断是否是关键路径,关键活动的语句

算法的时间复杂度:n个顶点e条边

有拓扑排序O(n+e),初始化O(n),20行也是O(n+e)

故最终是O(n+e)

(图)关键路径算法 (含AOV AOE网比较)相关推荐

  1. 【数据结构和算法笔记】AOE网和关键路径

    目录 AOE网的概念: 关键路径:(critical  path) 求关键路径和关键活动: 事件的最早开始时间(event early): 事件的最迟开始时间(event late): 活动的最早开始 ...

  2. 软件项目活动图关键路径算法演示(转载)

    如上图,是一个AOE网,点表示状态,边表示活动及其所需要的时间.为了求出关键路径,我们使用一下算法: 1.求出到达各个状态的最早时间(按最大计) 这个过程是要从源点开始向汇点顺推: V1是源点,其最早 ...

  3. DAG 图关键路径算法

    关键路径 如果DAG图拓扑有序,那么此图可以转换成线性的先后关系,而不需要回退去访问数据.如果项目安排的事件拓扑有序,那么此项目中的各个事件的依存关系不可以解耦,不会形成连环套而致使项目无法开展.项目 ...

  4. AOE网活动的最早、最迟发生时间及关键路径问题

    免费浏览请前往:https://zhuanlan.zhihu.com/p/337438327 上个学期学数据结构的时候有学到,这学期的离散数学又要考..复习复习 有向图中,用顶点表示事件,用有向边表示 ...

  5. 有向无环图—关键路径详解(最通俗易懂的版本)【数据结构】

    文章目录 有向无环图 拓扑排序 AOV-网 AOE-网 关键路径的概念 事件的最早/晚开始时间 事件和活动的区分 活动的最早/晚开始时间 有向无环图 拓扑排序 AOV-网 由于有向无环图可以用一种自然 ...

  6. 算法笔记_图算法专题_关键路径 AOV网和AOE网

    关键路径 1.基本概念 1.AOV网:顶点活动网,是指用顶点表示活动,而用边集表示活动优先关系的有向无环图. 2.AOE网:边活动网,是指用带权的边集表示活动,而用顶点表示事件的有向无环图. AOV网 ...

  7. 图的应用(AOV网、AOE网、图连通性)

    图的应用(AOV网.AOE网.图连通性): AOV网: 在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,称这样的有向图为顶点表示活动的网,简称AOV网. AOV网特点: 1.AO ...

  8. 【算法】 AOV网与AOE网

    AOV网 我们把施工过程.生产流程.软件开发.教学安排等都当成一个项目工程来对待,所有的工程都可以分为若干个"活动"的子工程.有很多场景对顺序有严格的要求,比如说建造一栋大楼必须先 ...

  9. 拓扑排序与关键路径(AOV网和AOE网)

    一.AOV网(Activity On Vertex Network) 在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,称为AOV网. 不能存在回路 ...

  10. [图] AOE网-关键路径|关键活动-原理、手算举例、C语言实现

    文章目录 AOE网 AOE的应用(AOE的相关概念) 原理:求关键活动和关键路径 求ve.vl(顶点) 求ee.el(边) 求关键路径,关键活动 手算举例 C语言实现 AOE网 [有向无环图]活动在边 ...

最新文章

  1. Linux入门时必学文件处理个命令
  2. 添加一个文件夹及一些文件如何使用git生成patch
  3. GMV突破1300亿,Lazada下一站去哪?
  4. 活照片 android,活照片app安卓
  5. 三菱880彩铅和uni的区别_冷灰素描纸与彩铅、色粉笔结合,一种复古味道
  6. 软件测试 学习之路 html基础
  7. 基于Protostuff的通用序列化、反序列化功能实现
  8. 12306排队是什么意思_12306火车网上订票排队是什么意思
  9. QComboBox使用讲解
  10. matlab或_Matlab下载安装教程
  11. Python办公自动化入门-Excel合并同类项内容
  12. react-navigation v6 中文极速版
  13. 星系炸弹(2015年蓝桥杯省赛第2题)
  14. “开源社”成立:众人同心,其利断金
  15. 安卓手机如何更改开机 关机 动画
  16. 往hive表中插入与导出数据方式load ,insert ,sqoop 等方式详解
  17. 怎么提高android播放器的网络带宽,使用GSYVideoPlayer增加显示实时网速
  18. 关注ERP项目中的隐含成本
  19. 北斗卫星导航产业重大应用示范项目落户哈市
  20. Linux 密码破解之 John the Ripper

热门文章

  1. 远程控制——一句话木马
  2. python高级用法使用手册(收藏)
  3. 24.UART串口通讯框图、波特率计算方法
  4. 模块化的ESP8266小电视设计与制作
  5. 【STM32H7的DSP教程】第22章 DSP矩阵运算-放缩,乘法和转置矩阵
  6. excel怎么设置打印区域_淘宝卖家想要打印快递单怎么设置
  7. mysql2000数据库四合一_sql2000四合一版下载|microsoft sql server2000 简体中文4合一版附sql 2000 sp4 补丁_ - 极光下载站...
  8. 零基础入门学习汇编语言~基础知识~机器语言与汇编语言的产生及组成
  9. ST7200.11固件门DIY全程记录[2009-05-03修复成功!]
  10. sns java_JEESNS首页、文档和下载 - Java 开源 SNS 社区系统