(16)有向无环图及其应用分析

合集下载

拓扑排序-有向无环图(DAG,DirectedAcyclicGraph)

拓扑排序-有向无环图(DAG,DirectedAcyclicGraph)

拓扑排序-有向⽆环图(DAG,DirectedAcyclicGraph)条件:1.每个顶点出现且只出现⼀次。

2.若存在⼀条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前⾯。

有向⽆环图(DAG)才有拓扑排序,⾮DAG图没有拓扑排序⼀说。

⼀般⽤有向边指⽰顺序关系,运⽤于顺序关系。

例如,下⾯这个图:显然是⼀个DAG图,1→4表⽰4的⼊度+1,4是1的邻接点,代码表⽰:前者deg[4]++;后者⽤vector[1].push(4)如何写出拓扑排序代码?1.⾸先将边与边的关系确定,建⽴好⼊度表和邻接表。

2.从⼊度为0的点开始删除,如上图显然是1的⼊度为0,先删除。

3.于是,得到拓扑排序后的结果是 { 1, 2, 4, 3, 5 }。

通常,⼀个有向⽆环图可以有⼀个或多个拓扑排序序列。

因为同⼀⼊度级别的点可以有不同的排序⽅式。

4.拓扑排序可以判断图中有⽆环,如下图显然4,5,6⼊度都是1,不存在⼊度为0的点,⽆法进⾏删除操作。

判断有⽆环的⽅法,对⼊度数组遍历,如果有的点⼊度不为0,则表明有环。

例题+代码拓扑排序(⼀)-Hiho-Coder1174描述由于今天上课的⽼师讲的特别⽆聊,⼩Hi和⼩Ho偷偷地聊了起来。

⼩Ho:⼩Hi,你这学期有选什么课么?⼩Hi:挺多的,⽐如XXX1,XXX2还有XXX3。

本来想选YYY2的,但是好像没有先选过YYY1,不能选YYY2。

⼩Ho:先修课程真是个⿇烦的东西呢。

⼩Hi:没错呢。

好多课程都有先修课程,每次选课之前都得先查查有没有先修。

教务公布的先修课程记录都是好多年前的,不但有重复的信息,好像很多都不正确了。

⼩Ho:课程太多了,教务也没法整理吧。

他们也没法⼀个⼀个确认有没有写错。

⼩Hi:这不正是轮到⼩Ho你出马的时候了么!⼩Ho:哎??我们都知道⼤学的课程是可以⾃⼰选择的,每⼀个学期可以⾃由选择打算学习的课程。

唯⼀限制我们选课是⼀些课程之间的顺序关系:有的难度很⼤的课程可能会有⼀些前置课程的要求。

第7章 图-有向无环图

第7章 图-有向无环图

算法的执行步骤: 算法的执行步骤: 1、用一个数组记录每个结点的入度。将入度为零的 、用一个数组记录每个结点的入度。 结点进栈。 结点进栈。 2、将栈中入度为零的结点V输出。 、将栈中入度为零的结点 输出 输出。 3、根据邻接表找到结点 的所有的邻接结点, 并将 、根据邻接表找到结点V的所有的邻接结点 的所有的邻接结点, 这些邻接结点的入度减一。 这些邻接结点的入度减一 。 如果某一结点的入度变 为零,则进栈。 为零,则进栈。
3
2
3、找到全为零的第 k 列,输出 k 、 4、将第 k 行的全部元素置为零 、 行的全部元素置为零
…………………
7
53、4;直至所有元素输出完毕。 、 ;直至所有元素输出完毕。
1 2 3 4 5 6 7
0 1 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0
template<class T> int BinaryTree <T>:: NumOfOne ( node <T> *t )
{ int k=0; if (t==NULL ) //空二叉树 //空二叉树 return 0; if (t所指结点 的度为 k=1 所指结点 的度为1) k=1; d1= NumOfOne ( t->lchild); //递归求左子树叶结点数 //递归求左子树叶结点数 d2= NumOfOne ( t->rchild); } //递归求右子树叶结点数 //递归求右子树叶结点数 return (d1+d2+k);
A B
AOE网络:结点为事件,有向边指向表示事件的执行次序。 网络:结点为事件,有向边指向表示事件的执行次序。 网络 有向边定义为活动,边的权值为活动进行所需要的时间。 有向边定义为活动,边的权值为活动进行所需要的时间。

《有向无环图的应用》课件

《有向无环图的应用》课件

基于拓扑排序的算法实现
总结词
拓扑排序适用于有向无环图,通过排序可以确定图中各节点的先后顺序。
详细描述
基于拓扑排序的算法实现主要利用拓扑排序的性质,从入度为0的节点开始,依次访问相邻节点,并 将已访问的节点从图中删除。如果所有节点都被访问过,则说明该图为有向无环图。
基于动态规划的算法实现
总结词
动态规划算法可以高效地解决有向无环 图中的最长路径和最短路径问题。
详细描述
在复杂的网络结构中,路由器需要使用有向 无环图来表示网络拓扑结构,通过图的顶点 和边来表示网络中的节点和连接关系。通过 有向无环图,路由器可以快速计算出数据包 从源到目的地的最佳路径,提高网络传输效 率。
数据库设计中的ER图生成
总结词
有向无环图在数据库设计中用于生成实体关系图(ER图),帮助设计人员更好地理解 和管理数据库结构。
在程序设计中,流程图是一种重要的工具, 用于表示程序的执行流程。有向无环图可以 用来生成流程图,通过顶点和边来表示程序 的各个步骤和它们之间的逻辑关系。通过流 程图,程序员可以更好地理解程序的执行过
程,发现潜在的逻辑错误并进行优化。
社交网络分析中的影响力传播
要点一
总结词
要点二
详细描述
有向无环图在社交网络分析中用于研究影响力传播,帮助 理解信息如何在社交网络中传播。
基于图的分解的构建方法
该方法是将一个有向无环图分解成若干个子图,每个子图都 是一个强连通子图,然后将这些子图进行排序,最后将它们 连接起来形成完整的有向无环图。
具体步骤包括:将有向无环图中的所有顶点按照强连通性进 行分类;对每个强连通子图进行拓扑排序;将所有强连通子 图的拓扑序列连接起来,形成一个完整的序列。

有向无环图的最优路径

有向无环图的最优路径

有向无环图的最优路径有向无环图(Directed Acyclic Graph,简称DAG)是一种图论中常见的数据结构,其中的有向边没有闭环。

在计算机科学和应用程序设计中,有向无环图的最优路径是一个重要的问题,它在许多领域都有广泛的应用,例如优化问题、动态规划和调度算法等。

在有向无环图中,最优路径是指从起始节点到目标节点的路径,使得路径上的权重之和最小或最大。

最优路径的选择取决于具体的应用场景和问题要求。

在本文中,我们将讨论求解有向无环图最优路径的算法和技巧。

一、拓扑排序拓扑排序是解决有向无环图最优路径问题的一种重要算法。

它通过对图的节点进行排序,使得任何一条边的起始节点都排在终止节点之前。

拓扑排序可以用来处理依赖关系,例如任务调度和编译器优化等问题。

在实现拓扑排序算法时,可以使用深度优先搜索(DFS)或广度优先搜索(BFS)等方法。

具体步骤如下:1. 初始化一个栈,用于存储已经访问过的节点。

2. 选择一个未访问的节点作为起始节点,将其标记为已访问。

3. 对于起始节点的每个未访问的邻接节点,递归调用拓扑排序算法。

4. 将当前节点入栈。

5. 重复步骤3和步骤4,直到所有节点都被访问。

6. 从栈顶到栈底的顺序即为拓扑排序的结果。

拓扑排序算法可以求解有向无环图的最优路径,例如,最长路径和最短路径等问题。

在实际应用中,我们可以根据具体需求选择不同的路径计算方法。

二、动态规划动态规划是解决有向无环图最优路径问题的另一种常用方法。

它通过将问题分解为子问题,并用一个表格来存储子问题的解,从而逐步构建出最优解。

在使用动态规划算法求解有向无环图最优路径时,可以使用以下步骤:1. 定义状态:将问题表示为一个状态集合,其中每个状态和图中的一个节点对应。

2. 定义状态转移方程:通过递推关系式来定义状态之间的转移关系,以得到最优路径。

3. 计算最优解:根据状态转移方程,从起始节点开始计算每个节点的最优路径值,并记录路径信息。

有向无环图及其应用

有向无环图及其应用
其中,v1为源点(入度为零的点);v9为汇点(出度为零的点)。
图7.21 一个AOE-网
第11页/共19页
②从vl(n-1) = ve(n-1)起向后递推 vl(i) = Min{vl(j)-dut(<i, j>)} <i, j>∈S, i = n-2, … , 0其中,S是所有以第i个顶点为尾的弧的集合。
Status CriticalPath (ALGraph G) { //G为有向网,输出G的各项关键活动。 if (!TopologicalOrder (G, T)) return ERROR; vl[0..G.vexnum-1] = ve[0..G.vexnum-1]; //初始化顶点事件的最迟发生时间
算法7.10如下:
第7页/共19页
count = 0; while (!StackEmpty (S)) { Pop (S, i); printf (i, G.vertices[i].data); //输出i号顶点并计数 ++ count; for (p = G.vertices[i].firstarc; p; p = p->nextarc) { k = p->adjvex; //对i号顶点的每个邻接点的入度减1 if (!(――indegree[k])) Push (S, k); //若入度减为0,则入栈 } // for } // while if (count < G.vexnum) return ERROR; //该有向图有回路 } // TopologicalSort
(5)关键路径算法
②算法实现 如①所述,计算各顶点的ve值是在拓扑排序的过程中进行的,需对拓扑排序的算法作如下修改: 1.在拓扑排序之前设初值,令ve[i]=0(0≤i≤n-1); 2.在算法中增加一个计算vj的之间后继vk的最早发生时间的操作:若ve(j) + dut(<j, k>) > ve[k],则ve[k]=ve(j) + dut(<j, k>); 3.为了能按逆拓扑有序序列的顺序计算各顶点的vl值,需记下在拓扑排序的过程中求得的拓扑有序序列,这需要在拓扑排序算法中,增设一个栈以记录拓扑有序序列,则在计算求得各顶点的ve值之后,从栈顶至栈底便为逆拓扑有序序列。

有向无环图

有向无环图

有向无环图有向无环图(DAG)是一种重要的图形数据结构,在计算机科学、网络和算法分析等领域中都有广泛的应用。

它与普通无向图有所不同,因为它会在连接时增加一个方向,这就意味着它可以表示有序的数据。

有向无环图被广泛应用于计算机科学领域,比如拓扑排序、分布式处理、编译器设计等等。

概念有向无环图是由一些顶点和一些有序的边组成,它将数据结构中的每个顶点连接起来。

每条边都有一个方向,这就决定了图中的有序性,也决定了如何遍历图中的每个顶点。

它只有在没有重复出现的边时,才能保证从一个顶点开始,能够遍历到整个图中的每个顶点。

另外一个特点是,它不能有环,也就是说,从一个顶点出发,不能回到该顶点本身。

拓扑排序有向无环图是一种很强大的数据结构,它可以用来实现拓扑排序(Topological Sorting)。

拓扑排序是一种重要的技术,可以根据有向边的方向,对顶点进行排序,以便给定时序性任务分配排序方式。

比如,在建筑工程中,需要用到拓扑排序,比如地基建完再搭框架,搭框架后再安装门窗等等。

拓扑排序能保证输出的顺序和输入的顺序一致,也可以用于求解最短路径问题,比如求解从一个城市到另外一个城市的最短路径。

分布式处理有向无环图也可以用来实现分布式处理(Distributed Processing),它可以把任务分解成一些独立的子任务,然后把它们连接起来,形成有向无环图,这样每一个子任务可以在不同的处理器上完成。

分布式处理可以使用有向无环图的拓扑排序算法,实现对任务的排序,从而保证任务的正确执行。

同时,由于它不存在环路,因此也可以保证它是安全的,不会出现死锁的情况,这样也就可以保证流程的有序性。

编译器设计有向无环图也可以用于编译器设计(Compiler Design)。

编译器是计算机科学中一种重要的应用,它可以把高级语言翻译成机器语言,从而可以让计算机处理高级语言编写的程序。

有向无环图可以用来构建编译器,因为它可以实现对语句的排序,这样可以保证编译器在编译过程中符合语法规则,并且能够正确翻译,从而使程序能够正确执行。

【全版】有向无环图及其应用推荐PPT

【全版】有向无环图及其应用推荐PPT

5
2021/7/29
数据结构
拓扑排序的方法和步骤: (1)在AOV网中选取一个没有前趋(即入 度为0)的顶点并输出之; (2)从AOV网中删除该顶点以及从该顶点 发出的所有有向边(可以用有向边射入的顶 点入度减1实现); (3)重复(1)、(2),直至全部顶点输 出完毕(称为拓扑排序成功),或者再也找 不到没有前趋的顶点(对应于拓扑排序失败, 即图中存在有向环)为止。
7.5 有向无环图及其应用
数据结构
有向无环图(directed acyline graph, DAG):
不存在由有向边构成的有向环 。
(1)AOV网 如果在图中,用顶点表示活动,弧表
示活动间的先后关系,则称这样的DAG图
为AOV网(Acivity On Vertex network)
1
2021/7/29
int vexnum,arcnum;
如果在图中,用顶点表示活动,弧表示 #define MAXVER 21
如果在带权的有向图中,用顶点表示事件,用有向边表示活动,边上的权表示活动持续的时间,这种带权的有向图称为AOE网
(Activity On Edge Network)。
活动间的先后关系,则称这样的DAG图 时间余量:A l (k)−Ae (k)表示完成活动ak的时间余量,它表示不延误工期的前提下活动ak可以延迟的时间。
/* 对
9
2021/7/29
数据结构
for(i=1;i<=G.vexnum;i++) /* 假定G
中各顶点入度未知,先求各顶点入度 */
G.vexs[i].indegree=0;
for(i=1;i<=G.vexnum;i++)

【图论】有向无环图的拓扑排序

【图论】有向无环图的拓扑排序

【图论】有向⽆环图的拓扑排序1. 引⾔有向⽆环图(Directed Acyclic Graph, DAG)是有向图的⼀种,字⾯意思的理解就是图中没有环。

常常被⽤来表⽰事件之间的驱动依赖关系,管理任务之间的调度。

拓扑排序是对DAG的顶点进⾏排序,使得对每⼀条有向边(u, v),均有u(在排序记录中)⽐v先出现。

亦可理解为对某点v⽽⾔,只有当v的所有源点均出现了,v才能出现。

下图给出有向⽆环图的拓扑排序:下图给出的顶点排序不是拓扑排序,因为顶点D的邻接点E⽐其先出现:2. 算法原理与实现拓扑排序的实现算法有两种:⼊度表、DFS,其时间复杂度均为O(V+E)。

⼊度表对于DAG的拓扑排序,显⽽易见的办法:找出图中0⼊度的顶点;依次在图中删除这些顶点,删除后再找出0⼊度的顶点;然后再删除……再找出……直⾄删除所有顶点,即完成拓扑排序为了保存0⼊度的顶点,我们采⽤数据结构栈(亦可⽤队列);算法的可视化可参看。

图⽤邻接表(adjacency list)表⽰,⽤数组inDegreeArray[]记录结点的⼊度变化情况。

C实现:// get in-degree arrayint *getInDegree(Graph *g) {int *inDegreeArray = (int *) malloc(g->V * sizeof(int));memset(inDegreeArray, 0, g->V * sizeof(int));int i;AdjListNode *pCrawl;for(i = 0; i < g->V; i++) {pCrawl = g->array[i].head;while(pCrawl) {inDegreeArray[pCrawl->dest]++;pCrawl = pCrawl->next;}}return inDegreeArray;}// topological sort functionvoid topologicalSort(Graph *g) {int *inDegreeArray = getInDegree(g);Stack *zeroInDegree = initStack();int i;for(i = 0; i < g->V; i++) {if(inDegreeArray[i] == 0)push(i, zeroInDegree);}printf("topological sorted order\n");AdjListNode *pCrawl;while(!isEmpty(zeroInDegree)) {i = pop(zeroInDegree);printf("vertex %d\n", i);pCrawl = g->array[i].head;while(pCrawl) {inDegreeArray[pCrawl->dest]--;if(inDegreeArray[pCrawl->dest] == 0)push(pCrawl->dest, zeroInDegree);pCrawl = pCrawl->next;}}}时间复杂度:得到inDegreeArray[]数组的复杂度为O(V+E);顶点进栈出栈,其复杂度为O(V);删除顶点后将邻接点的⼊度减1,其复杂度为O(E);整个算法的复杂度为O(V+E)。

判断一个图是否有环无向图有向图讲解

判断一个图是否有环无向图有向图讲解

一、无向图:方法1:如果存在回路,则必存在一个子图,是一个环路。

环路中所有顶点的度〉=2。

n算法:第一步:删除所有度<=1的顶点及相关的边,并将另外与这些边相关的其它顶点的度减一。

第二步:将度数变为1的顶点排入队列,并从该队列中取出一个顶点重复步骤一。

如果最后还有未删除顶点,则存在环,否则没有环。

n算法分析:由于有m条边,n个顶点。

i)如果m〉=n,则根据图论知识可直接判断存在环路。

(证明:如果没有环路,则该图必然是k棵树 k>=1.根据树的性质,边的数目m = n-k.k〉=1,所以:m<n)ii)如果m〈n 则按照上面的算法每删除一个度为0的顶点操作一次(最多n次),或每删除一个度为1的顶点(同时删一条边)操作一次(最多m次).这两种操作的总数不会超过m+n。

由于m〈n,所以算法复杂度为O(n).注:该方法,算法复杂度不止O(V),首先初始时刻统计所有顶点的度的时候,复杂度为(V + E),即使在后来的循环中E>=V,这样算法的复杂度也只能为O(V + E)。

其次,在每次循环时,删除度为1的顶点,那么就必须将与这个顶点相连的点的度减一,并且执行delete node from list[list[node]],这里查找的复杂度为list[list[node]]的长度,只有这样才能保证当degree[i]=1时,list[i]里面只有一个点。

这样最差的复杂度就为O(EV)了.方法2:DFS搜索图,图中的边只可能是树边或反向边,一旦发现反向边,则表明存在环。

该算法的复杂度为O(V).方法3:摘自:http:///lzrzhao/archive/2008/03/13/2175787。

aspxPS:此方法于2011—6-12补充假定:图顶点个数为M,边条数为E遍历一遍,判断图分为几部分(假定为P部分,即图有 P 个连通分量)对于每一个连通分量,如果无环则只能是树,即:边数=结点数-1只要有一个满足边数 > 结点数-1原图就有环将P个连通分量的不等式相加,就得到:P1:E1=M1-1P2:E2=M2—1.。

有向无环图的最优路径

有向无环图的最优路径

有向无环图的最优路径有向无环图(Directed Acyclic Graph,简称DAG)是一种图的数据结构,它定义了一组有向边,并且不存在任何环路。

在此基础上,我们将讨论有向无环图的最优路径问题。

一、什么是最优路径在有向无环图中,最优路径指的是从图中的某一起点到终点的最短路径或者最长路径,其长度可根据具体情况来决定。

这里我们将重点讨论求解最短路径的问题。

二、最优路径的应用最优路径在许多领域都有广泛的应用。

例如,在交通规划中,我们希望找到最短路径以减少行程时间和交通拥堵。

在电信网络中,最短路径算法使得数据能够高效地传输。

另外,最优路径还可以应用于任务调度、路径规划等领域。

三、有向无环图的最优路径算法有向无环图的最优路径可以通过动态规划算法来求解。

下面介绍两种较为常用的算法:迪杰斯特拉算法和贝尔曼-福特算法。

1. 迪杰斯特拉算法迪杰斯特拉算法是一种典型的单源最短路径算法,适用于有向无环图。

它的基本思想是从起点开始,逐步确定到达各个顶点的最短路径。

算法步骤如下:(1)初始化:将起点的最短路径设置为0,其他顶点的最短路径设置为无穷大。

(2)选择:选择一个未被访问过的顶点,使得当前被访问的顶点到该顶点的路径长度最短。

(3)更新:通过比较当前路径长度和新路径长度的大小,更新到达其他未被访问过的顶点的最短路径。

(4)重复:重复选择和更新步骤,直到所有顶点都被访问过。

2. 贝尔曼-福特算法贝尔曼-福特算法是一种通用的最短路径算法,适用于一般的有向图,包括带有负权边的图。

算法步骤如下:(1)初始化:将起点的距离设置为0,其他顶点的距离设置为无穷大。

(2)迭代:重复对所有边进行松弛操作,即通过比较当前路径和新路径的长度,更新距离数组中的值。

(3)判断负权环:若经过上述迭代,距离数组仍然在更新,则存在负权环,无法求解最短路径。

四、最优路径的应用举例以城市之间的交通规划为例,假设我们已经构建了一个有向无环图,其中城市之间的道路表示为有向边,而道路的长度表示为边的权重。

有向无环图及其应用

有向无环图及其应用

有向树, 图7.15 有向树,DAG图和有向图一例 图和有向图一例
(2)表达式子式共享 ) 例如,下述表达式 例如,下述表达式((a +b ) * (b * (c + d)) + (c + d) * e) * ((c + d) * e),用 , 二叉树表示如图7.16所示,用有向无环图表示如图7.17所示. 所示, 所示. 二叉树表示如图 所示 用有向无环图表示如图 所示 * + * + a b b c * + d 图7.16 用二叉树描述表达式 c + d * e c + d * e
count = 0; while (!StackEmpty (S)) { Pop (S, i); printf (i, G.vertices[i].data); //输出 号顶点并计数 输出i号顶点并计数 输出 ++ count; for (p = G.vertices[i].firstarc; p; p = p->nextarc) { - k = p->adjvex; //对i号顶点的每个邻接点的入度减 号顶点的每个邻接点的入度减1 - 对 号顶点的每个邻接点的入度减 if (!(――indegree[k])) Push (S, k); //若入度减为 ,则入栈 若入度减为0, 若入度减为 } // for } // while if (count < G.vexnum) return ERROR; //该有向图有回路 该有向图有回路 } // TopologicalSort
v6 → v1 → v 4 → v3 → v 2 → v5
£7.5.3 关键路径
(1)定义 ) 关键路径( ):在 网中有些活动可以并行的进行, 关键路径(Critical Path):在AOE-网中有些活动可以并行的进行, ): 网中有些活动可以并行的进行 所以完成工程的最短时间是从开始点到完成点的最长路径的长度( 所以完成工程的最短时间是从开始点到完成点的最长路径的长度(路径 长度是指路径上各活动持续时间之和,而不是路径上弧的数目). ).这个 长度是指路径上各活动持续时间之和,而不是路径上弧的数目).这个 路径长度最长的路径叫关键路径. 路径长度最长的路径叫关键路径. 关键活动: 的活动. 关键活动:l(i) = e(i)的活动.即活动的最早开始时间=最迟开始时间. 的活动 即活动的最早开始时间=最迟开始时间. 显然,关键路径上的所有活动都是关键活动. 显然,关键路径上的所有活动都是关键活动. (2)AOE-网 ) 网 AOE-网(Activity On Edge):即边表示活动的网.AOE-网是一个 网 ):即边表示活动的网 ):即边表示活动的网. 网是一个 带权的有向无环图.其中,顶点表示事件(Event),弧表示活动,权 带权的有向无环图.其中,顶点表示事件( ),弧表示活动, ),弧表示活动 表示活动持续的时间. 表示活动持续的时间.

给定一个包含n个点m条边的有向无环图

给定一个包含n个点m条边的有向无环图

给定一个包含n个点m条边的有向无环图一、重要概念1. 图、简单图、图的同构、度序列与图序列、补图与自补图、两个图的联图、两个图的积图、偶图图:一个图是一个有序对<V, E>,记为G=(V, E),其中:1) V是一个有限的非空集合,称为顶点集合,其元素称为顶点或点。

用|V|表示顶点数;2) E是由V中的点组成的无序对构成的集合,称为边集,其元素称为边,且同一点对在E中可以重复出现多次。

用|E|表示边数注:图G 的顶点集记为V(G),边集记为E(G)。

图G 的顶点数(或阶数)和边数可分别用符号n(G)和m(G)表示简单图:无环无重边的图称为简单图。

(除此之外全部都是复合图)注:点集与边集均为有限集合的图称为有限图。

只有一个顶点而无边的图称为平凡图。

边集为空的图称为空图图的同构:设有两个图G1=(V1, E1)和G2=(V2, E2),若在其顶点集合间存在双射,使得边之间存在如下关系:设u1↔u2, v1↔v2,u1, v1∈V1,u2, v2∈V2;u1v1∈E1当且仅当u2v2∈E2,且u1v1与u2v2 的重数相同。

称G1与G2同构,记为G1≌G2 图的度序列:一个图G的各个点的度d1, d2,…, dn构成的非负整数组(d1, d2,…, dn)称为G的度序列注:非负整数组(d1, d2,…., dn)是图的度序列的充分必要条件是:∑di 为偶数。

度序列的判定问题为重点!图的图序列:一个非负数组如果是某简单图的度序列,称它为可图序列,简称图序列补图:对于一个简单图G=(V, E),令集合E1={uv|u≠v, u, v ∈V},则图H=(V,E1\E)称为G的补图自补图:若简单图G与其补图同构,则称G为自补图注:自补图的性质(1)若n阶图G是自补的,即那么有联图:设G1,G2是两个不相交的图,作G1+G2,并且将G1中每个顶点和G2中的每个顶点连接,这样得到的新图称为G1与G2的联图。

有向无环图及应用共24页

有向无环图及应用共24页

谢谢!

26、我们像鹰一样,生来就是自由的 ,但是 为了生 存,我 们不得 不为自 己编织 一个笼 子,然 后把自 己关在 里面。 ——博 莱索

27、法律如果不讲道理,即使延续时 间再长 ,也还 是没有 制来的。 ——马 克罗维 乌斯

29、在一切能够接受法律支配的人类 的状态 中,哪 里没有 法律, 那里就 没有自 由。— —洛克

30、风俗可以造就法律,也可以废除 法律。 ——塞·约翰逊
有向无环图及应用
61、奢侈是舒适的,否则就不是奢侈 。——CocoCha nel 62、少而好学,如日出之阳;壮而好学 ,如日 中之光 ;志而 好学, 如炳烛 之光。 ——刘 向 63、三军可夺帅也,匹夫不可夺志也。 ——孔 丘 64、人生就是学校。在那里,与其说好 的教师 是幸福 ,不如 说好的 教师是 不幸。 ——海 贝尔 65、接受挑战,就可以享受胜利的喜悦 。——杰纳勒 尔·乔治·S·巴顿

图论:有向图和无向图,有环和无环

图论:有向图和无向图,有环和无环

图论:有向图和⽆向图,有环和⽆环
有向⽆环图:为什么不能有环,有环会导致死循环。

检查⼀个有向图是否存在环要⽐⽆向图复杂。

(有向图为什么⽐⽆向图检查环复杂呢?)
现实中管⽹会存在环吗?管⽹是有⽅向的,理论上也是⽆环的。

arcgis有向⽆环图最短路径。

有向⽆环图和⼆叉树的关系:如何确定⽗节点和⼦节点[没有⽗节点的就是⽗节点,没有⼦节点的就是叶⼦节点] 有向⽆环图并不⼀定能转化成树【那能不能把有向⽆环图劈开成多棵树】
⼀个⽆环的有向图称做有向⽆环图(Directed Acyclic Graph)。

简称DAG 图。

DAG 图是⼀类较有向树更⼀般的特殊有向图,如图给出了有向树、DAG 图和有向图的例⼦。

虽然DAG图是更⼀般的有向图,但是依然可以使⽤树的判断公式来判断复杂度。

判断是否有环:
1. 起点编码和终点编码是否相等
从OBJECTID为1的开始遍历:下⼀个点是否与OBJECTID为1的相等。

如果相等,则回到起点,为环。

>>性质:有向⽆环图的⽣成树个数等于⼊度⾮零的节点的⼊度积。

有向⽆环图⽣成树:
(百度百科上不是说有向⽆环图不⼀定能转换成树吗?严格意义上,树的叶⼦节点只有⼀个⽗节点)
DAG(有向⽆环图)能否转化为树?:
如果说⼀个叶⼦节点有两个⽗节点,会怎么样
有向⽆环图不⼀定能只⽣成⼀棵树,但是可以⽣成多棵树。

但是这样就破坏了什么信息呢?。

数据结构第7章图3有向无环图及其应用ppt课件

数据结构第7章图3有向无环图及其应用ppt课件
while (!StackEmpty(S)) { Pop(S,i); printf(i,G.vertices[i].data); ++count; //输出i号顶点并计数
for(p=G.vertices[i].firstarc; p; p=p->nextarc){ k=p—>adivex;//对i号顶点的每个邻接点入度减1 if(!(--indegree[k])) Push(S,k); //若入度减为0,则入栈
§7.5 有向无环图及其应用
❖有向无环图
在工程实践中,一个工程项目往往由若干个子项 目组成,这些子项目间往往有多种关系:
①先后关系,即必须在一子项目完成后,才能开 始实施另一个子项目;
②子项目之间无次序要求,即两个子项目可以同 时进行,互不影响。
§7.5 有向无环图及其应用
❖两种常用的活动网络(Activity Network)
3
4 4^
4
2 1^ 3^
1^
s
0 V1 3 V4
5 V6
4
V2 1 V3 2 V5 4
indegree[0..5] 0 0 0 0 0 0 012345
最后输出的拓扑序列为:v6v1v3v2v4v5
§7.5 有向无环图及其应用
G.vertices[0] v1
3
2
G.vertices[1] v打2 印^G.vertices[4].data
1. 输入AOV网络。令 n 为顶点个数。 2. 在AOV网络中选一个没有直接前驱的顶点, 并输出之; 3. 从图中删去该顶点, 同时删去所有它发出的有向边; 4. 重复以上 2、3 步, 直到:
全部顶点均已输出,拓扑有序序列形成,拓扑排序完成 或者,图中还有未输出的顶点,但已跳出处理循环。这说 明图中还剩下一些顶点,它们都有直接前驱,再也找不到 没有前驱的顶点了。这时AOV网络中必定存在有向环。

判断一个图是否有环无向图有向图讲解

判断一个图是否有环无向图有向图讲解

一、无向图:方法1:∙如果存在回路,则必存在一个子图,是一个环路。

环路中所有顶点的度>=2。

∙ n算法:第一步:删除所有度<=1的顶点及相关的边,并将另外与这些边相关的其它顶点的度减一。

第二步:将度数变为1的顶点排入队列,并从该队列中取出一个顶点重复步骤一。

如果最后还有未删除顶点,则存在环,否则没有环。

∙ n算法分析:由于有m条边,n个顶点。

i)如果m>=n,则根据图论知识可直接判断存在环路。

(证明:如果没有环路,则该图必然是k棵树k>=1。

根据树的性质,边的数目m = n-k。

k>=1,所以:m<n)ii)如果m<n 则按照上面的算法每删除一个度为0的顶点操作一次(最多n次),或每删除一个度为1的顶点(同时删一条边)操作一次(最多m次)。

这两种操作的总数不会超过m+n。

由于m<n,所以算法复杂度为O(n)。

∙注:该方法,算法复杂度不止O(V),首先初始时刻统计所有顶点的度的时候,复杂度为(V + E),即使在后来的循环中E>=V,这样算法的复杂度也只能为O(V + E)。

其次,在每次循环时,删除度为1的顶点,那么就必须将与这个顶点相连的点的度减一,并且执行delete node from list[list[node]],这里查找的复杂度为list[list[node]]的长度,只有这样才能保证当degree[i]=1时,list[i]里面只有一个点。

这样最差的复杂度就为O(EV)了。

方法2:DFS搜索图,图中的边只可能是树边或反向边,一旦发现反向边,则表明存在环。

该算法的复杂度为O(V)。

方法3:摘自:/lzrzhao/archive/2008/03/13/2175787.aspx PS:此方法于2011-6-12补充假定:图顶点个数为M,边条数为E遍历一遍,判断图分为几部分(假定为P部分,即图有P 个连通分量)对于每一个连通分量,如果无环则只能是树,即:边数=结点数-1只要有一个满足边数> 结点数-1原图就有环将P个连通分量的不等式相加,就得到:P1:E1=M1-1P2:E2=M2-1...PN:EN>MN-1所有边数(E) > 所有结点数(M) - 连通分量个数(P)即: E + P > M 所以只要判断结果 E + P > M 就表示原图有环,否则无环.实例代码如下:1.#include<iostream>2.#include<malloc.h>ing namespace std;4.#define maxNum 100 //定义邻接举证的最大定点数5.int visited[maxNum];//通过visited数组来标记这个顶点是否被访问过,0表示未被访问,1表示被访问6.int DFS_Count;//连通部件个数,用于测试无向图是否连通,DFS_Count=1表示只有一个连通部件,所以整个无向图是连通的7.int pre[maxNum];8.int post[maxNum];9.int point;//pre和post的值10.11.//图的邻接矩阵表示结构12.typedef struct13.{14.char v[maxNum];//图的顶点信息15.int e[maxNum][maxNum];//图的顶点信息16.int vNum;//顶点个数17.int eNum;//边的个数18.}graph;19.void createGraph(graph *g);//创建图g20.void DFS(graph *g);//深度优先遍历图g21.void dfs(graph *g,int i);//从顶点i开始深度优先遍历与其相邻的点22.void dfs(graph *g,int i)23.{24.//cout<<"顶点"<<g->v[i]<<"已经被访问"<<endl;25. cout<<"顶点"<<i<<"已经被访问"<<endl;26. visited[i]=1;//标记顶点i被访问27. pre[i]=++point;28.for(int j=1;j<=g->vNum;j++)29. {30.if(g->e[i][j]!=0&&visited[j]==0)31. dfs(g,j);32. }33. post[i]=++point;34.}35.36.void DFS(graph *g)37.{38.int i;39.//初始化visited数组,表示一开始所有顶点都未被访问过40.for(i=1;i<=g->vNum;i++)41. {42. visited[i]=0;43. pre[i]=0;44. post[i]=0;45. }46.//初始化pre和post47. point=0;48.//初始化连通部件数为049. DFS_Count=0;50.//深度优先搜索51.for(i=1;i<=g->vNum;i++)52. {53.if(visited[i]==0)//如果这个顶点为被访问过,则从i顶点出发进行深度优先遍历54. {55. DFS_Count++;//统计调用void dfs(graph *g,int i);的次数56. dfs(g,i);57. }58. }59.}60.void createGraph(graph *g)//创建图g61.{62. cout<<"正在创建无向图..."<<endl;63. cout<<"请输入顶点个数vNum:";64. cin>>g->vNum;65. cout<<"请输入边的个数eNum:";66. cin>>g->eNum;67.int i,j;68.//输入顶点信息69.//cout<<"请输入顶点信息:"<<endl;70.//for(i=0;i<g->vNum;i++)71.// cin>>g->v[i];72.//初始画图g73.for(i=1;i<=g->vNum;i++)74.for(j=1;j<=g->vNum;j++)75. g->e[i][j]=0;76.//输入边的情况77. cout<<"请输入边的头和尾"<<endl;78.for(int k=0;k<g->eNum;k++)79. {80. cin>>i>>j;81. g->e[i][j]=1;82. g->e[j][i]=1;//无向图对称83. }84.}85.int main()86.{87. graph *g;88. g=(graph*)malloc(sizeof(graph));89. createGraph(g);//创建图g90. DFS(g);//深度优先遍历91.//连通部件数,用于判断是否连通图92. cout<<"连通部件数量:";93. cout<<DFS_Count<<endl;94.if(DFS_Count==1)95. cout<<"图g是连通图"<<endl;96.else if(DFS_Count>1)97. cout<<"图g不是连通图"<<endl;98.//各顶点的pre和post值99.for(int i=1;i<=g->vNum;i++)100. cout<<"顶点"<<i<<"的pre和post分别为:"<<pre[i]<<" "<<post[i]<<endl;101.//cout<<endl;102.//判断无向图中是否有环103.if(g->eNum+DFS_Count>g->vNum)104. cout<<"图g中存在环"<<endl;105.else106. cout<<"图g中不存在环"<<endl;107.int k;108. cin>>k;109.return 0;110.}111./*112.输入:113.正在创建无向图...114.请输入顶点个数vNum:10115.请输入边的个数eNum:9116.请输入边的头和尾117.1 2118.1 4119.2 5120.2 6121.4 7122.5 9123.6 3124.7 8125.9 10126.*/注意:有向图不能使用此方法。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
有向无环图 及其应用
1
一、定义
一个无环的有向图称为有向无环图,简写为 DAG(directed acycline graph)。 与有向二叉树相比,有向无环图是更一般的特 殊有向图。 实例:
有向树
有向无环图
有向图
有向无环图的一个简单应用: 用有向无环图描述 2 算术表达式。
二、拓扑排序
1.引例:现有计算机课程12门,如下表所示:
C3,C6 无 C9
C11
C12
普通物理
数值分析
C9
C9,C10,C1
3
二、拓扑排序
2.拓扑排序:
C4 C5 C2 C1 C3 C7
C12 C9 C10 C8
C6 C11
偏序是指集合中仅有部分元素可比较大小(或先后);
4 全序是指集合中所有元素均可比较大小(或先后)。
二、拓扑排序
2.拓扑排序:
C4 C5 C2 C1 C3 C7
9
二、拓扑排序
4.算法说明:为了使说明过程简单起见,我们以下 图为例:
G.adjlist[0] G.adjlist[1] G.adjlist[2] G.adjlist[3] G.adjlist[4] G. adjlist[5] v1 v2 ^ v3 v4 v5 ^ v6 4 3 ^ 4 4 ^ 1 ^ 3 2 1 ^
for(i=0;i<G.vexnum;++i) indegree[0..G.vexnum-1]=0; 0 1 G. adjlist[0] v1 3 2 1 ^ v1 v2 for(i=0;i<G.vexnum;++i){ G. adjlist[1] v2 ^ p=G. adjlist[i].firstedge; 2 3 G. adjlist [2] v3 4 1 ^ while (p){ v3 v4 G. adjlist[3]k=p->adjvex; v4 4 ^ 4 G. adjlist[4]++indegree[k]; v5 ^ 5 v6 v5 p=p->nextadj; G. adjlist[5] v6 4 3 ^ } 另外增设一个存放各顶点的入度值的一维数组 indegree: }
拓扑序列:C1 C2 C3 C4 C5 C7 C9 C10 C11 C6 C12 C8
8
二、拓扑排序
3.方法: 注意1 :从某种意义下来说,拓扑排序的结果是不 唯一的。 注意2 :这种以顶点表示活动的有向无环图称为活动 在顶点的网,简称AOV(Activity On Vertex Network) 网。 注意3 :当有向图中包含有向环路时,拓扑排序算法 结束时图中还有若干顶点没有被输出(即有向环路 中的所有顶点没有参加排序)。
0 1 2 3 4 5
12
二、拓扑排序
4.算法说明:为了使说明过程简单起见,我们以下 图为例:
G. adjlist[0] G. adjlist[1] G. adjlist[2] G. adjlist[3] G. adjlist[4] Gadjlist [5] v1 v2 ^ v3 v4 v5 ^ v6 4 3 ^ 4 4 ^ 1 ^ 3 2 1 ^
0
v1
v2
1
s
3
v4 v3
C6 C11
6
二、拓扑排序
3.方法:
C4 C5 C2 C1 C3 C7
C12 C9 C10 C8
C6 C11
拓扑序列:C1 C2 C3 C4 C5 C7 C9 C10 C11 C6 C12 C8
7
二、拓扑排序
3.方法: 注意1 :从某种意义下来说,拓扑排序的结果是不 唯一的。 注意2 :这种以顶点表示活动的有向无环图称为活动 在顶点的网,简称AOV(Activity On Vertex Network) 网。
先修课程
C1
C1
程序设计基础
离散数学 数据结构 C3

C1 C1,C2
C7
C2 C3
C4
C5
C9
汇编语言
语言的设计和分析 C12 计算机组成原理
C10
C1
C3,C4 C11 C5,C3
C6 C8
C6 C7 C8 C9 C10
C11
编译原理 操作系统原理 高等数学 线性代数
0 indegree[0..5] }//FindInDegree 0 2 1 1 2 2 3 3 4 0 5
11
二、拓扑排序
拓扑排序算法思想: 4.算法说明:为了使说明过程简单起见,我们以下 ①设一个栈S,所有入度为0的顶点 图为例: 的序号进栈。如0,5 进栈。 0 1 G. adjlist[0] v1 3 2 1 ^ v1 v2 count=0(打印顶点个数计数器)。 Gadjlist [1] v2 ^ ②当栈S不空时,出栈一个元素并打 2 3 印相应顶点的值; count 加 1。 G. adjlist[2] v3 4 1 ^ v3 v4 该顶点的所有邻接点的入度减 1, G. adjlist [3] v4 4 ^ 减1后所有入度为0的顶点的序号进栈。 4 Gadjlist [4] v5 ^ 5 ③重复第二步,直至栈空时转④。 v6 v5 G. adjlist[5] v6 4 3 ^ ④若count=G.vexnum,则拓扑排序成 功;否则图中必有环路,拓扑排序失 另外增设一个存放各顶点的入度值的一维数组indegree: 败。 indegree[0..5] 0 2 1 2 3 0
vertex
adjvexnextadj firstedge
0
v1
v2
1
3
v4
v3
2
5
4
v5
v6
另外增设一个存放各顶点的入度值的一维数组indegree:
indegree[0..5] 0 0 2 1 1 2 2 3 3 4 0 5
10
二、拓扑排序
indegree一维数组初值的程序: 4.求 算法说明:为了使说明过程简单起见,我们以下 FindInDegree(ALGraph G,indegree[0..G.vexnum-1]){ 图为例:
C12 C9 C10 C8
C6 C11
拓扑排序是指将一个偏序关系转化为全序关系的过程 的特殊操作。 5
二、拓扑排序
3.方法: ①在有向图中选择一个没有前驱(即 入度为0)的顶点并输出之。
C2 C1 C4 C5
②在有向图中删除刚刚输出的顶点及 C3 所有以该顶点为尾的弧。
C12
C7
C9
③图中若不再有入度为 0的顶点,则 C8 C10 结束;否则转①。
相关文档
最新文档