没有合适的资源?快使用搜索试试~ 我知道了~
图论算法.doc
4星 · 超过85%的资源 需积分: 0 209 下载量 188 浏览量
2007-08-01
09:26:52
上传
评论
收藏 177KB DOC 举报
温馨提示
试读
21页
物超所值,绝对经典!!
资源推荐
资源详情
资源评论
图论算法
§1 最小生成树
1.1 生成树的概念
设图 G=(V,E)是一个连通图,当从图中任一顶点出发遍历图 G 时,将边集 E(G)分成两个集合 A(G)和
B(G)。其中 A(G)是遍历图时所经过的边的集合,B(G)是遍历图时未经过的边的集合。显然,G1=(V,A)
是图 G 的子图,则称子图 G1 是连通图 G 的生成树。图的生成树不是惟一的。如对图 1(a),当按深度和广
度优先搜索法进行遍历就可以得到图 1 中(b)和(c)的两棵不同的生成树,并分别称之为深度优先生成树和
广度优先生成树。
对于有 n 个顶点的连通图,至少有 n-1 条边,而生成树中恰好有 n-1 条边,所以连通图的生成树是该图
的极小连通子图。若图 G 的生成树中任意加一条边属于边集 B(G)中的边,则必然形成回路。
求解生成树在许多领域有实际意义。例如,对于供电线路或煤气管道的铺设问题,即假设要把 n 个城市
联成一个供电或煤气管道网络,则需要铺设 n-1 条线路。任意两城市间可铺设一条线路,n 个城市间最
多可能铺设 n(n-1)/2 条线路,各条线路的造价一般是不同的。一个很实际的问题就是如何在这些可能的
线路中选择 n-1 条使该网络的建造费用最少,这就是下面要讨论的最小生成树问题。
1.2 网的最小生成树
在前面我们已经给出图的生成树的概念。这里来讨论生成树的应用。
假设,要在 n 个居民点之间敷设煤气管道。由于,在每一个居民点与其余 n-1 个居民点之间都可能敷
设煤气管道。因此,在 n 个居民点之间,最多可能敷设 n(n-1)/2 条煤气管道。然而,连通 n 个居民点之间
的管道网络,最少需要 n-1 条管道。也就是说,只需要 n-1 条管道线路就可以把 n 个居民点间的煤气管道
连通。另外,还需进一步考虑敷设每一条管道要付出的经济代价。这就提出了一个优选问题。即如何在
n(n-1)/2 条可能的线路中优选 n-1 条线路,构成一个煤气管道网络,从而既能连通 n 个居民点,又能使总
的花费代价最小。
解决上述问题的数学模型就是求图中网的最小生成树问题。把居民点看作图的顶点,把居民点之间的煤
气管道看作边,而把敷设各条线路的代价当作权赋给相应的边。这样,便构成一个带权的图,即网。对于
一个有 n 个顶点的网可以生成许多互不相同的生成树,每一棵生成树都是一个可行的敷设方案。现在的问
题是应寻求一棵所有边的权总和为最小的生成树。
如何构造这种网的最小生成树呢?下面给出这样一种解法:
(1)已知一个网,将网中的边按其权值由小到大的次序顺序选取。
(2)若选某边后不形成回路,则将其保留作为树的一条边;若选某边后形成回路,则将其舍弃,以后也
不再考虑。
(3)如此依次进行,直到选够(n-1)条边即得到最小生成树。
现以图 2 为例说明此算法。设此图是用边集数组 EV 表示的,且数组中各边是按权值由小到大的次序排
列,如下表所示。
k 1 2 3 4 5 6 7 8 9 10
EV[k].p1 2 2 4 2 6 5 1 1 1 5
EV[k].p2 3 4 3 6 4 7 5 6 2 6
COST[EV[k].p1,EV[k].p2] 5 6 10 11 14 18 19 21 27 33
按权值由小到大选取各边就是在数组中按下标 k 由 1 到 en(图中边数)的次序选取。选前 2 条边(2,3),
(2,4)时均无问题,保留作为树的边;到第 3 条边(4,3)时将与已保留的边形成回路,将其舍去;同样继
续做:保留(2, 6);舍去(6,4);保留(5,7),(1,5),(1,6),此时,保留的边数已够(n-1)=6 条边,此
时必定将 7 个顶点全部互相连通了,后面剩下的边(1,2),(5,6)就不必再考虑了。最后得到的最小生成
树如图 2a 中深色边所示,其各边权值总和等于 80。由离散数学中的图论可以证明,这就是最小生成树了,
其权值最小。当图中有权值相等的边时,其最小生成树可能有不同的选取方案。
实现此算法的关键是,在选取某条边时应判断是否与已保留的边形成回路。
这可用将各顶点划分为集合的办法解决:假设数组 tag(1..en)作为顶点集合划分的标志初值为 0。在算
法的执行过程中,当所选顶点 u,v 是连通的,则将相应位置的 tag[u],tag[v]置以相同的数字,而不连通
的点在初期分属不同的集合,置不同的数字;一旦两个不同的连通分支连通了,则修改 tag 的值,将新的
连通分支改为相同的数字。我们以图 2 为例。首先选(2,3)(2,4)边,由于是连通的,并且不出现回路。
tag[2]:=1,tag[3]:=tag[4]:=1 是同一个集合 A;选(6,2)边与 A 集合连通;tag[6]:=1;再选(5,7)与集合
A 不连通,tag[5]:= tag[7]:=2 构成另一集合 B;选(1,5)边与集合 B 连通,tag [1]:=2;此时,集合 A=
{2,3,4,6};集合 B={5,7,1};当选(1,6)边时,(1,6)与集合 A、集合 B 都连通,并且两个顶点分
别属于两个不同的集合 A、B,这使得集合 A 与集合 B 通过边(1,6)连通。修改集合 B 中 tag 的值,置为
1,即将集合 B 并入集合 A。边为 n-1 条,这就是一棵最小生成树。
根据集合标志数组 tag 的变化过程,很容易判断,选择一条新的边是否构成回路。当新选边的两个顶点
u、v,若 tag[u]和 tag[v]相同并且均不等于 0 时,即 u,v 已在生成树集合中被保留过,加入 u,v 后即形
成回路,不能选。而当 tag [u]<>tag[v]或者 tag[u]=tag[v]=0 时,可以选并且不形成回路,说明 u,v 中至
少有一个顶点未被选过或者被选过的 u、v 分别属于两个不同的集合,此时选择 u,v 可以将含 u 的集合与
含 v 的集合连通,修改 tag 数组。如此下去,到所有顶点均已属于一个集合时,此最小生成树就完全构成
了。
网的最小生成树算法描述如下:
假设算法中用到的数据结构是经过处理的。
COST(1..n,1..n)是带权数组存放网中顶点之间的权。EV(1..n*(n-1/2))按权从小到大存放排序后的顶点
对,即 EV[K].P1 存放一个顶点,边的另一顶点存放在 EV[K].P2 之中。
tag(1..n):顶点集合划分标志的数组。
Enumb:当前生成树的边数。
SM:当前权累计和。
;;
;
:=!;"#$%!&诸参量初始化'
($%)&边数累计'
*+ ,%-).(,=.
/$%0(12);$%0(123; &选一对顶点/,'
4./,; &找到含顶点 / 的集合 '5
4.,*; &找到含顶点 的集合 *'
4,6*+
7,; $% 8); &最小生成树增加一条边'
"#$%"#8"0,1;
#,*;&选 , 不会形成环,合并 ,* 集合,并修改 '
9
:$%:8)&找下一条边'
9
4 ,-)+7;<;
"7"#
.;
由算法可知图 2 的最小生成树的结果是(2,3),(2,4),(2,6),(5,7),(1,5),(1,6)。
§2 最短路径
在一个赋权有向图上寻找最短路径问题也是图应用的一个重要课题。
假定图 3 中的有向图 G=(V,E)是一个航空图,V 的每一顶点表示—个城市,正中的每条弧 v—>w 表示
从城市 v 到城市 W 的航线,弧 V—>w 上的标号代表从 V 城飞到 w 城所需要的时间。要寻找由该航空图上
一给定城市到另一城市所需要的最短飞行时间。可以用求解这个有向图的单源最短路径算法来完成。
下面,我们讨论求解单源最短路径问题的贪心算法,也称 Dijkstra 算法。
设有向图 G=(V,E),其中,V={1,2,…,n).cost 是表示 G 的邻接矩阵,cost[i,j]表示有向边(i,j)
的权。若不存在有向边(i,j),则 cost[i,j]的权为无限大(oo)。令 S 是一个集合,其中的每个元素表示一个
顶点,从源点到这些顶点的最短距离已经求出。
(1)令顶点 V0 为源点,集合 S 的初态只包含顶点 V0,即 S={V0}。数组 dist 记录从源点到其他各顶点当
前的最短距离,其初值为 dist[i]:=cost[v0,i],(i=2,…,n)。
(2)从 S 之外的顶点集合 V-S 中选出一个顶点 W,使 dist[W]的值最小。于是,从源点到达 W 只通过 S
中的顶点,我们把 W 加入集合 S。
(3)调整 dist 中记录的从源点到 V-S 中每个顶点 V 的距离:从原来的 dist[v]和 dist[w]+cost[w,v]中选择
较小的值作为新的 dist[v]。
(4)重复上述过程(2)和(3),直到 S 中包含 V 的全部顶点。
最终数组 dist 记录了从源点到 V 中其余各顶点的最短路径。
对图 3 所示的加权有向图应用 Dijkstra 算法,从源点 V2 出发到达各顶点的最短路径如下表所示。
最短路径
---------------------------------------
源点 中间顶点 终止顶点 长度
3=)!
>)=
>?>!
>)>=
@
--------------------------------------
对图 > 的执行过程:初始时,"=&3',90)1=,90>1=)=,90?1=,90=1=
)!,90@1=,第一遍处理时,*=3 使 90=1最小、于是把 = 加入 "。然后,调整 9 中从源点到
其余各顶点的距离:90>1=)=,为次小,将 > 加入 "。90?1=03,>180>,?1%)=8)==
>!,经中间点 >。"=&3,=,>,?',同理,90)1=03,>180>,)1=>=,"=
&3,=,>,?,)',由于 3 没有一条到 @ 的路径,所以 90@1%。
555由此我们给出最短路径算法如下
<<;9;<;",!;
54*$%).
590*1$%0!,*1&最短路径初始化值'
55540!,*1,A
555+<0*1$%!;&< 记载当前最短路径'
59
5"$%0!1$%);&到达点集合 " 和到达点 " 个数初值'
5*+,-).&最后一点已无选择余地'
5*$%A;$%!
5554*$%).
555554*".90*1,*
55555+/$%*;*$%90719
55555&找最小 9071'
555"$%"80/1$%8)&/ 为找到最短路径的终点'
5554*$%).
5554*".90/180/,*1,90*1
555+90*1$%90/180/,*1&调整非 " 集各点最短路径值'
55555<0*1$%/; &调整非 " 集各点最短路径'
5559
555$%8)
59
.;
+9<;";!
54$%).
54"
5+($%
5555*+(,6!.
555557(;($%<0(19&通过找前趋点,反向输出最短路径'
55557(;7B901
5559
5"7,!;7B;A;9
.;
容易看出,算法 << 的时间复杂度为
3
,空间复杂度为 。
剩余20页未读,继续阅读
资源评论
- 神速2013-12-21对我很有用 ~~
- chia__2016-04-09实用,谢谢分享!
mudaoming002
- 粉丝: 0
- 资源: 27
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 最入门的爬虫代码 python.docx
- 爬虫零基础入门-爬取天气预报.pdf
- 最通俗易懂的 MongoDB 非结构化文档存储数据库教程.zip
- 以mongodb为数据库的订单物流小项目.zip
- 腾讯云-mongodb数据库, 项目部署.zip
- 腾讯 APIJSON 的 MongoDB 数据库插件.zip
- 理解非关系型数据库和关系型数据库的区别.zip
- 操作简单的Mongodb网页web管理工具,基于Spring Boot2.0支持mongodb集群.zip
- tms-mongodb-web,提供访问mongodb数据的REST API和可灵活扩展的mongodb web 客户端.zip
- SpringBoot整合mongodb学习MongoTemplate和MongoRepository两种方式CRUD使用.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功