预览加载中,请您耐心等待几秒...
1/10
2/10
3/10
4/10
5/10
6/10
7/10
8/10
9/10
10/10

亲,该文档总共57页,到这已经超出免费预览范围,如果喜欢就直接下载吧~

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

拓扑排序(páixù)与关键路径7.5有向无环图及其应用 拓扑排序 问题提出:学生选修课程问题 顶点——表示课程 有向弧——表示先决条件,若课程i是j的先决条件,则图中有弧<i,j> 学生应按怎样的顺序学习这些(zhèxiē)课程,才能无矛盾、顺利地完成学业——拓扑排序 定义 AOV网——用顶点表示活动,用弧表示活动间优先关系的有向图称为顶点表示活动的网(ActivityOnVertexnetwork),简称AOV网 若<vi,vj>是图中有向边,则vi是vj的直接前驱;vj是vi的直接后继 AOV网中不允许有回路,这意味着某项活动以自己为先决条件拓扑排序——把AOV网络中各顶点按照它们相互之间的优先关系排列成一个线性序列的过程叫~ 检测AOV网中是否存在环方法(fāngfǎ):对有向图构造其顶点的拓扑有序序列,若网中所有顶点都在它的拓扑有序序列中,则该AOV网必定不存在环 拓扑排序的方法(fāngfǎ) 在有向图中选一个没有前驱的顶点且输出之 从图中删除该顶点和所有以它为尾的弧 重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止例C1C1C2C4C6C6算法实现 以邻接表作存储结构 设置一个(yīɡè)包含n个元素的一维数组indegree,保存AOV网中每个顶点的入度值。 把邻接表中所有入度为0的顶点进栈 栈非空时,输出栈顶元素Vj并退栈;在邻接表中查找Vj的直接后继Vk,把Vk的入度减1,即indegree[k]-1;若Vk的入度为0则进栈 重复上述操作直至栈空为止。若栈空时输出的顶点个数不是n,则有向图有环;否则,拓扑排序完毕算法(suànfǎ)分析--算法(suànfǎ)7.12关键(guānjiàn)路径 问题提出定义 AOE网(ActivityOnEdge)——也叫边表示活动的网。AOE网是一个带权的有向无环图,其中顶点表示事件,弧表示活动,权表示活动持续时间(shíjiān) 路径长度——路径上各活动持续时间(shíjiān)之和 关键路径——路径长度最长的路径叫~ Ve(j)——表示事件Vj的最早发生时间(shíjiān) Vl(j)——表示事件Vj的最迟发生时间(shíjiān) e(i)——表示活动ai的最早开始时间(shíjiān) l(i)——表示活动ai的最迟开始时间(shíjiān) l(i)-e(i)——表示完成活动ai的时间(shíjiān)余量 关键活动——关键路径上的活动叫~,即l(i)=e(i)的活动问题分析 如何找e(i)=l(i)的关键(guānjiàn)活动?求关键路径步骤(bùzhòu) 求Ve(i) 求Vl(j) 求e(i) 求l(i) 计算l(i)-e(i)算法实现 以邻接表作存储结构 从源点V1出发,令Ve[1]=0,按拓扑序列求各顶点的Ve[i] 从汇点Vn出发,令Vl[n]=Ve[n],按逆拓扑序列求其余各顶点的Vl[i] 根据各顶点的Ve和Vl值,计算(jìsuàn)每条弧的e[i]和l[i],找出e[i]=l[i]的关键活动算法描述 1-输入顶点和弧信息(xìnxī),建立其邻接表 计算每个顶点的入度 2-对其进行拓扑排序 2.1-排序过程中求顶点的Ve[i] 2.2-将得到的拓扑序列进栈 3-按逆拓扑序列求顶点的Vl[i] 4-计算每条弧的e[i]和l[i],找出e[i]=l[i]的关键活动StatusTopologicalOrder(ALGraphG,Stack&T){//算法7.13 //有向网G采用邻接表存储结构,求各顶点事件的最早发生时间ve(全局变量)。 //T为拓扑序列定点栈,S为零入度顶点栈。 //若G无回路,则用栈T返回G的一个拓扑序列,且函数值为OK,否则(fǒuzé)为ERROR。 StackS;intcount=0,k; charindegree[40]; ArcNode*p; InitStack(S); FindInDegree(G,indegree);//对各顶点求入度indegree[0..vernum-1] for(intj=0;j<G.vexnum;++j)//建零入度顶点栈S if(indegree[j]==0)Push(S,j);//入度为0者进栈 InitStack(T);//建拓扑序列顶点栈T count=0; for(inti=0;i<G.vexnum;i++)ve[i]=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[