当前位置: 首页 > news >正文

数据结构 -- 图的应用(二)

图的应用

有向无环图(DAG)

有向无环图:若一个有向图中不存在环,则称为有向无环图,简称DAG图

DAG描述表达式

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

方法:

利用规律:最终有向无环图中,定点中不会出现重复的操作数

step1:把各个操作数不重复地排成一排

step2:标出各个运算符生效的顺序(先后顺序有点出入无所谓)

step3:按顺序加入运算符,注意分层

step4:自底向上逐层检查同层地运算符是否合体

使用有向无环图描述表达式结果不唯一
在这里插入图片描述

AOV网

AOV网用定点表示活动的网

用DAG图(有向无环图)表示一个工程。顶点表示活动,有向边<vi,vj>表示活动vi必须先于活动vj进行

在这里插入图片描述

拓扑排序

找到要做事的先后顺序

实现:

① 从AOV网中选择一个没有前驱(入度为0)的顶点并输出

② 从网中删除该顶点和所有以它为起点的有向边

③ 重复①和②直到当前的AOV为空或当前网中不存在无前驱的顶点为止(说明存在回路)

#define MaxVertexNum 100
typedef struct AcrNode{  //边表结点int adjvex;struct ArcNode *nextarc;		//指向下一条弧的指针//InfoType info		//网的边权值
}ArcNode;
typedef struct VNode{	//顶点表结点VertexType data;	//顶点信息ArcNode *firstarc;		//指向第一条依附该顶点的弧的指针
}VNode,AdjList[MaxVertexNum];
typedef struct{AdjList wertices;	//邻接表int vexnum,arcnum;	//图的顶点数和弧数}Graph;
bool TopologicalSrot(Graph G){initStack(S);for(int i = 0;i<G.vexnum;i++){if(indegree[i] == 0)Push(s,i);		//将所有入度为0的顶点进栈}int count = 0;		//计数,记录当前已经输出的顶点数while(!isEmpty(S)){		//栈不空,则存在入度为0的顶点Pop(S,i);			//栈顶元素出栈print[count++]=i;		//输出顶点ifor(p=G.vertices[i].firstarc;p;p=p->nextarc){//将所有i指向的顶点的入度减1,并且将入度减为0的顶点压入栈s中v = p->adjvex;if(!(--indegree[v]))Push(S,v);		//入度为0,则入栈}}//whileif(count<G.vexnum)return false;		//排序失败,说明有向图中有回路elsereturn true;		//拓扑排序成功
}
逆拓扑排序

对于一个AOV网,如果采用下列步骤进行排序,则称之为逆拓扑排序:

① 从AOV网中选择一个没有后继(出度为0)的顶点并输出

② 从网中删除该顶点和所有以它为起点的有向边

③ 重复①和②直到当前的AOV为空

【思考】使用不同的存储结构对时间复杂度的影响

如果使用邻接表进行存储,要对所有边进行遍历才能找到顶点的出度,时间复杂度高(低效)

邻接矩阵更方便些

【补充】

逆邻接表:每个顶点连接的顶点是指向当前顶点的顶点

逆拓扑排序的实现(DFS算法)
void DFSTraverse(Graph G){		//对图G进行深度优先遍历for(v = 0;v<G.vexnum;++v)visited[v] = FALSE;		//初始化已访问标记数据for(v = 0;v<G.vexnum;++v)	//本代码中是从v=0开始遍历if(!visited[v])DFS(G.v);
}
void DFS(Graph G,int v){		//从顶点v出发,深度优先遍历图Gvisit(v);					//访问顶点vvisited[v] = TRUE;			//设已访问标记for(w = FirstNeighbor(G,v);w>=0;w = NextNeighbor(G,v,w))if(!visited[w]){		//w为u的尚未访问的邻接顶点DFS(G,w);}	//if
}

DFS实现逆拓扑排序:在顶点退栈前输出

AOE网

在带权有向图中,以顶点表示事件,以有点改变表示活动,以边上的权值表示完成该活动的开销(如完成活动所需的时间),称之为用边表示活动的网络,简称AOE网

在这里插入图片描述

性质:

① 只有在某顶点所代表的事件发生后,从该顶点出发阿德各有向边所代表的活动才能开始

② 只有在进入某顶点的各有向边所代表的活动都已结束时,该顶点所代表的事件才能发生

另外,有些活动是可以并发进行的

关键路径

在AOE网中仅有一个入度为0的顶点,称为开始顶点(源点),在所有路径中,具有最大路径长度称为关键路径,而把关键路径上的活动称为关键活动

完成整个工程的最短时间就是关键路径的长度,若关键活动不能按时完成,则整个工程的完成时间就会延长

在这里插入图片描述

事件vk的最早发生时间ve(k) – 决定了所有从vk开始的活动能够开工的最早时间

活动ai最早开始时间e(i)) – 指该活动弧的起点所表示的事件的最早发生时间

事件vk的最是发生时间vl(k) – 指在不推迟整个过程完成的前提下,该时间最迟必须发生时间

活动ai的最迟开始时间l(i) – 指该活动弧的重点所表示事件的最迟发生时间与该活动所需时间之差

在这里插入图片描述

时间余量为零的活动为关键活动

由关键活动组成的路径就是关键路径

求关键路径的步骤

① 求各个事件的最早发生时间

按照拓扑排序序列,依次求各个顶点的ve(k)

② 求所有事件的最迟发生时间

按逆拓扑排序,依次求各个顶点的vl(k)

③ 求所有活动的最早发生时间

④求所有活动的最迟发生时间

⑤ 求所有活动的时间余量

关键活动、关键路径的特性

若关键活动耗时增加,则整个工程的工期将增长

缩短关键活动的时间,可以缩短整个工程的工期

当缩短到一定程度,关键路径可能会变成非关键活动

相关文章:

  • MinecraftPVP发展史
  • TypeScript之type
  • 轻松上手:使用 Docker Compose 部署 TiDB 的简易指南
  • 多模态革命!拆解夸克AI相机技术架构:如何用视觉搜索重构信息交互?(附开源方案对比)
  • 6.进程概念(中)
  • TCP vs UDP:核心区别、握手过程与应用场景(附对比图)
  • Git-基本操作
  • 人工智能数学基础(一):人工智能与数学
  • 什么是公共数据?公共数据开放后如何提高新质生产力发展?
  • SQL知识点合集---第二弹
  • 软考-软件设计师中级备考 5、数据结构 树和二叉树
  • 高级数据库对象全面解析:视图、存储过程与触发器
  • HTML5 WebSocket:实现高效实时通讯
  • 喷泉码技术在现代物联网中的应用的总结和参考文献
  • 人工智能数学基础(二):初等数学
  • UniApp 实现分享功能
  • uniapp打包apk如何实现版本更新
  • “数字驱动·智建未来——2025河北省建筑电气与智能化技术交流大会”
  • C++实时统计数据均值、方差和标准差
  • python如何用递归函数求1+2+3+4+5的值
  • 黄仁勋访华期间表示希望继续与中国合作,贸促会回应
  • 伊朗南部港口火势蔓延,部分集装箱再次发生爆炸
  • 伊朗港口爆炸致18死800余伤,三分之二伤者已出院
  • 申花四连胜领跑中超,下轮榜首大战对蓉城将是硬仗考验
  • 文化体验+商业消费+服务创新,上海搭建入境旅游新模式
  • 识味顺德︱顺德菜的醉系列与火滋味