一、图的定义和术语
1、有向图(Directed graph)
<vi,vj>::=vi→vj≠<vj,vi>
G=(V,{A})
V为顶点的有穷非空集合
{A}为顶点之间的关系集合
2、无向图(Undirected graph)
(vi,vj)=(vj,vi):=the same edge
G=(V,{E})
V为顶点的有穷非空集合
{E}为顶点之间的关系集合,即边集合
设n为顶点数,e为边或弧的条数
对Undirectedgraph有:0≤e≤n(n-1)/2
Directed graph 有:0≤e≤n(n-1)
完全图(Complete graph):边达到最大的图
无向完全图:边数为n(n-1)/2的无向图
有向完全图:弧数为n(n-1)的有向图
权:与图的边或弧相关的数
网:边或弧上带有权值的图
顶点的度TD(V):
无向图:为依附于顶点V的边数
有向图:等于以顶点V为弧头的弧数(V的入度,记为ID(V))与以顶点V为弧尾的弧数(出度,OD(V))之和。即:TD(V)= ID(V)+ OD(V)
路径Path from vp to vq:{vp,vi1,vi2,……,vin,vq},其中(vp,vi1),(vi1,vi2),……,(vin,vq)或者< vp,vi1>,……,< vin,vq >属于E(G)或A(G)
路径长度Length of a path:路径上边或弧的数目
简单路径 Simple path:路径中不含相同顶点的路径
回路或环Cycle:首尾顶点相同的路径,称为回路或环。即(v=vi0,vi1,……,vim=v’=v)
简单回路Simple cycle:除首尾顶点外,路径中不含相同顶点的回路
顶点连通:若顶点v到顶点v’有路径
无向连通图:若无向图中任意两个顶点vi,vj都是连通的,称该图是连通图(vi<>vj)
有向连通图:若有向图中任意两个顶点vi,vj,都存在从vi到vj和vj到vi的路径,称该图为强连通图(vi<>vj)
无向连通分量:无向图中极大连通子图,称连通分量
有向图强连通分量:有向图中极大强连通子图,称强连通分量
生成树:设无向图G是含有n个顶点的连通图,则图G的生成树是含有n个顶点,且只有n-1条边的连通子图。
二、图的存储结构
邻接矩阵
设图G=(V,{E})有n个顶点,则G的邻接矩阵定义为n阶方阵adj_mat。
无向邻接矩阵是对称矩阵
特点:判断两个顶点vi与vj是否关联,只需判A[i][j]是否为1
邻接表:将矩阵中每一行转化为一个链表
无向图邻接表
对图中每个顶点vi建立一个单链表,链表中的结点表示依附于顶点vi的边,每个链表结点有两个域
adjvex | nextarc |
adjvex:邻接点域,记载与顶点vi邻接的顶点信息;
nextarc:链域,指向下一个与顶点vi邻接的链表p结点
每个链表附设一个头结点,头结点结构:
vexdata | firstarc |
vexdata:存放顶点信息(姓名、编号等);firstarc:指向链表的第一个结点。
Degree(i)=numberof nodes in adjvex[i] (if G is undirected)
特点:设无向图中顶点数为n,边数为e,则它的邻接表需要n个头结点和2e个表结点。
有向图邻接表
与无向图的邻接表结构一样,只是在第i条链表上的结点是以vi为弧尾的各个弧头顶点
有向图逆邻接表
与有向图的邻接表结构一样,只是在第i条链表上的结点是以vi为弧头的各个尾顶点
三、图的遍历
从图中某个顶点出发,沿路径使图中每个顶点被访问且仅被访问一次的过程,称为遍历图。
两种常用遍历图的方法:深度优先搜索、广度优先搜素
1. 深度优先搜索(depth-first-search)~(stack)
(1)访问指定的某顶点V,将V作为当前顶点
(2)访问当前顶点的下一未被访问过的邻接点,并以该邻接点作为当前顶点
(3)重复(2),直到所有和当前顶点有路径相通的顶点都被访问到
(4)沿搜索路径回退,退到尚有邻接点未被访问过的某结点
(5)将该结点作为当前结点,重复以上步骤,直到所有顶点被访问过为止。
2.广度优先搜索(level-order traversal)~(queue)
(1)首先访问指定顶点v0,将v0作为当前顶点
(2)访问当前顶点的所有未访问过的邻接点,依次将访问的这些邻接点作为当前顶点
(3)重复(2),直到所有顶点被访问为止
生成树——是无向连通图G的某个连通子图
三大要素:
(1)n个顶点
(2)n-1条边
(3)连通(不能有回路)
生成树代价:
对图中每条边赋于一个权值(代价),则构成一个网,网的生成树G’={V,{T}}的代价是T中各边的权值之和,最小生成树就是网上所有可能的生成树中,代价最小的一类生成树。
最小生成树也不一定唯一。
1、如果在生成树上再增加任一条边,将形成回路cycle
2.生成树是最小子图。即:G’G,并且V(G’)=V(G),G’是连通的,E(G’)是E(G)的最小集。
G是连通的,则e≥n-1
G是连通的并且e=n-1,则G是一棵树
但是e=n-1不能说明它是一棵生成树,可能有回路
3.可以利用MST特性来设计最小生成树算法
最小生成树性质MST
设N=(V,{E})是一个连通网,U是顶点集V的一个非空子集。
若(u,v)是一条具有最小权值的边,其中u∈U,v∈V-U,即(u,v)=Min{cost(x,y)| x∈U,y∈V-U}则必存在一棵包含边(u,v)的最小生成树。
普里姆(Prim)最小生成树算法
设N=(V,{E})是一个连通网,V={1,2,……,n}是N的顶点集合,
辅助集合U,初值为{U0},用来存放当前所得到的最小生成树的顶点;
辅助集合TE,初值为{},用来存放当前所得到的最小生成树的边。
Prim算法步骤
1.TE=,U={u0}
2.当U≠V,重复下列步骤:
(1)选取(u0,v0)=min{cost(u,v)| u∈U,v∈V-U},保证不能形成回路
(2)TE=TE+(u0,v0),边(u0,v0)并入TE
(3)U=U+{V0},顶点V0并入U
克鲁斯卡尔(Kruskal)最小生成树算法
Kruskal算法是逐步给生成树T中添加不和T中的边构成回路的当前最小代价边。
特点:以最小代价边主
设N=(V,{E})是一个连通网,算法步骤为:
1.置生成树T的初始状态T=(V,{ })
2.当T中边数<n-1时,重复下列步骤:
从E中选取代价最小的边(v,u),并删除之;
若(v,u)依附的顶点v和u落在T中不同的连通分量上,则将边(v,u)并入到T的边集中;否则,舍去该边,选择下一条代价最小的边。
四、拓扑排序(topological sort)
拓扑排序时一种对非线性结构的有向图进行线性化的重要手段
Activity On Vertex(AOV)Networks
AOV Network::=有向图G中顶点V(G)代表活动activities(e.g. the course),边E(G)代表活动的优先关系C1->C3表示C1是C3的先驱课程
AOV网可解决如下两个问题:
(1)判定工程的可行性。有回路,整个工程就无法结束
(2)确定各项活动在整个工程执行中的先后顺序。称这种先后顺序为拓扑有序序列。
算法步骤:
(1)在AOV网中,选取一个没有前驱的顶点输出;
(2)删除该顶点和所有以它为弧尾的弧;
(3)重复以上两步,直到AOV网中全部顶点都已输出(得到拓扑有序序列)或者,图中再无没有前驱的顶点(AOV网中有环,不可行)
五、关键路径
Activity On Edge (AOE) Networks
有向图中,顶点表示事件,弧表示活动,弧上的权表示完成该活动所需的时间,称这类有向图为边表示活动的网
AOE网中仅有一个入度为0的事件,称为源点,它表示工程的开始;网中也仅有一个出度为0的事件,称为汇点,表示工程结束。
每一事件V表示以它为弧头的所有活动已经完成,同时,也表示以它为弧尾的所有活动可以开始。
AOE网可以解决如下问题
(1)估算工程的最短工期(从源点到汇点至少需要多少时间)
(2)找出哪些活动是影响整个工程进展的关键
路径长度:路径上各活动持续时间的总和,即:路径上所有弧的权值之和
关键路径:从源点到汇点之间路径长度最长的路径,(不一定唯一)
事件V1的最早发生时间ve(i):从源点到Vi的最长路径长度
活动aj的最早开始时间e(i):等于该活动的弧尾时间Vj的最早发生时间,即若<j,k>表示活动ai,则有e(i)=ve(j)
事件vk的最迟发生时间vl(k):是在不推迟整个工期的前提下,该事件最迟必须发生的时间
活动ai的最迟开始时间L(i):是该活动的弧头时间的最迟发生时间与该活动的持续时间只差,即L(i)=vl(k)-ai的持续时间
关键活动:l(i)=e(i)的活动
关键路径算法思想
从ve(l)=0开始利用下面递推公式,计算出各事件的最早发生时间
ve(j)=max{ve(i)+dut(<i,j>)},j=2,……,n <i,j>∈T
其中:T是所有以j为头的弧集合,dut(<i,j>表示活动的持续时间
从vl(n)=ve(n)开始,利用下面递推公式,计算出各事件的最迟发生时间:
vl(i)=min{vl(j)-dut(<i,j>)},i=n-1,……,1 <i,j>∈S
其中:S是所有以i为尾的弧集合,dut(<i,j>)表示活动的持续时间
设活动a由弧<j,k>表示,其中持续时间为dut(<j,k>),则利用下面公式,计算出各活动的最早,最迟开始时间:e(i)=ve(j) l(i)=vl(k)- dut(<j,k>)
找出e(i)=l(i)的活动,即为关键活动,诸关键活动组成的从源点到汇点的路径即为关键路径
关键路径上的活动都是关键活动
缩短非关键活动都不能缩短整个工期