《小生成树算法及其应用.ppt》由会员分享,可在线阅读,更多相关《小生成树算法及其应用.ppt(17页珍藏版)》请在三一办公上搜索。
1、最小生成树算法及应用,一、生成树的概念,若图是连通的无向图或强连通的有向图,则从图中任意一个顶点出发调用一次bfs或dfs后,便可以系统地访问图中所有顶点;若图是有根的有向图,则从根出发通过调用一次dfs或bfs,亦可系统地访问所有顶点。在这种情况下,图中所有顶点加上遍历过程中经过的边所构成的子图,称为原图的生成树。,对于不连通的无向图和不是强连通的有向图,若有根或者从根外的任意顶点出发,调用一次bfs或dfs后,一般不能系统地访问所有顶点,而只能得到以出发点为根的连通分支(或强连通分支)的生成树。要访问其它顶点,还需要从没有访问过的顶点中找一个顶点作为起始点,再次调用bfs或dfs,这样得到
2、的是生成森林。,由此可以看出,一个图的生成树是不唯一的,不同的搜索方法可以得到不同的生成树,即使是同一种搜索方法,出发点不同亦可导致不同的生成树。,可以证明:具有n个顶点的带权连通图,其对应的生成树有n-1条边。,最小生成树算法及应用,最小生成树算法及应用,二、求图的最小生成树算法,严格来说,如果图G=(V,E)是一个连通的无向图,则把它的全部顶点V和一部分边E构成一个子图G,即G=(V,E),且边集E能将图中所有顶点连通又不形成回路,则称子图G是图G的一棵生成树。,对于带权连通图,生成树的权即为生成树中所有边上的权值总和,权值最小的生成树,称为图的最小生成树。,求图的最小生成树具有很高的实际
3、应用价值,比如下面的这个例题。,最小生成树算法及应用,例1、城市公交网问题描述 有一张城市地图,图中的顶点为城市,无向边代表两个城市间的连通关系,边上的权为在这两个城市之间修建高速公路的造价,研究后发现,这个地图有一个特点,即任一对城市都是连通的。现在的问题是,要修建若干高速公路把所有城市联系起来,问如何设计可使得工程的总造价最少。输入 n(城市数,1=n=100);e(边数);以下e行,每行3个数i,j,wij,表示在城市i,j之间修建高速公路的造价。输出 n-1行,每行为两个城市的序号,表明这两个城市间建一条高速公路。,最小生成树算法及应用,举例 下面的图(A)表示一个5个城市的地图,图(
4、B)、(C)是对图(A)分别进行深度优先遍历和广度优先遍历得到的一棵生成树,其权和分别为20和33,前者比后者好一些,但并不是最小生成树,最小生成树的权和为19。,问题分析 出发点:具有n个顶点的带权连通图,其对应的生成树有n-1条边!那么选哪n-1条边呢?设图G的度为n,G=(V,E)我们介绍两种基于贪心的算法,Prim算法和Kruskal算法。,最小生成树算法及应用,1、用Prim算法求最小生成树的思想如下:设置一个顶点的集合S和一个边的集合TE,S和TE的初始状态均为空集;选定图中的一个顶点K,从K开始生成最小生成树,将K加入到集合S;重复下列操作,直到选取了n-1条边:选取一条权值最小
5、的边(X,Y),其中XS,not(YS);将顶点Y加入集合S,边(X,Y)加入集合TE;得到最小生成树T=(S,TE)。,如何证明Prim算法的正确性呢?提示:用反证法。因为操作是沿着边进行的,所以数据结构宜采用边集数组表示法。,最小生成树算法及应用,从文件中读入图的邻接矩阵g;边集数组elist初始化;For i:=1 To n-1 Do Begin elisti.fromv:=1;elisti.endv:=i+1;elisti.weight:=g1,i+1;End;求出最小生成树的n-1条边;For k:=1 To n-1 Do Begin min:=maxint;m:=k;For j:=
6、k To n-1 Do 查找权值最小的一条边 If elistj.weightk Then Begin t:=elistk;elistk:=elistm;elistm:=t;End;把权值最小的边调到第k个单元 j:=elistk.endv;j为新加入的顶点 For i:=k+1 To n-1 Do 修改未加入的边集 Begin s:=elisti.endv;w:=gj,s;If welisti.weight Then Begin elisti.weight:=w;elisti.fromv:=j;End;End;End;输出;,Prim算法的实现,最小生成树算法及应用,2、用Kruskal算法
7、求最小生成树的思想如下:设最小生成树为T=(V,TE),设置边的集合TE的初始状态为空集。将图G中的边按权值从小到大排好序,然后从小的开始依次选取,若选取的边使生成树T不形成回路,则把它并入TE中,保留作为T的一条边;若选取的边使生成树形成回路,则将其舍弃;如此进行下去,直到TE中包含n-1条边为止。最后的T即为最小生成树。,如何证明呢?,最小生成树算法及应用,Kruskal算法在实现过程中的关键和难点在于:如何判断欲加入的一条边是否与生成树中已保留的边形成回路?我们可以将顶点划分到不同的集合中,每个集合中的顶点表示一个无回路的连通分量,很明显算法开始时,把所有n个顶点划分到n个集合中,每个集
8、合只有一个顶点,表明顶点之间互不相通。当选取一条边时,若它的两个顶点分属于不同的集合,则表明此边连通了两个不同的连通分量,因每个连通分量无回路,所以连通后得到的连通分量仍不会产生回路,因此这条边应该保留,且把它们作为一个连通分量,即把它的两个顶点所在集合合并成一个集合。如果选取的一条边的两个顶点属于同一个集合,则此边应该舍弃,因为同一个集合中的顶点是连通无回路的,若再加入一条边则必然产生回路。,就是并查集的思想。,最小生成树算法及应用,将图的存储结构转换成边集数组表示的形式elist,并按照权值从小到大排好序;设数组C1.n-1用来存储最小生成树的所有边,Ci是第i次选取的可行边在排好序的el
9、ist中的下标;设一个数组S1.n,Si都是集合,初始时Si=i。i:=1;获取的第i条最小生成树的边 j:=1;边集数组的下标 While im2 Then Begin 找到的elist第j条边满足条件,作为第i条边保留 Ci:=j;i:=i+1;sm1:=sm1+sm2;合并两个集合 sm2:=;另一集合置空 End;j:=j+1;取下条边,继续判断 End;输出最小生成树的各边:elistCi,Kruskal算法的实现,最小生成树算法及应用,二、求图的最小生成树算法小结,都是基于贪心算法,时间复杂度均为O(n*n),Prim算法和Kruskal算法,三、应用举例例2、最优布线问题(wir
10、e.?)学校有n台计算机,为了方便数据传输,现要将它们用数据线连接起来。两台计算机被连接是指它们时间有数据线连接。由于计算机所处的位置不同,因此不同的两台计算机的连接费用往往是不同的。当然,如果将任意两台计算机都用数据线连接,费用将是相当庞大的。为了节省费用,我们采用数据的间接传输手段,即一台计算机可以间接的通过若干台计算机(作为中转)来实现与另一台计算机的连接。现在由你负责连接这些计算机,你的任务是使任意两台计算机都连通(不管是直接的或间接的)。输入格式 输入文件第一行为整数n(2=n=100),表示计算机的数目。此后的n行,每行n个整数。第x+1行y列的整数表示直接连接第x台计算机和第y台
11、计算机的费用。输出格式 输出文件只有一个整数,表示最小的连接费用。样例输入 样例输出3 2(注:表示连接1和2,2和3,费用为2)0 1 21 0 12 1 0,机器蛇,在未来的某次战争中,我军计划了一次军事行动,目的是劫持敌人的航母。由于这个计划高度保密,你只知道你所负责的一部分:机器蛇的通信网络。计划中要将数百条机器蛇投放到航母的各个角落里。由于航母内部舱室、管线错综复杂,且大部分由金属构成,因此屏蔽效应十分强烈,况且还要考虑敌人的大强度电子干扰,如何保持机器蛇间的联系,成了一大难题。每条机器蛇的战斗位置由作战计划部门制定,将会及时通知你。每条机器蛇上都带有接收、发射系统,可以同时与多条机
12、器蛇通讯。由于整个系统承载的数据量庞大,需要一个固定的通讯网络。情报部门提供了极其详尽的敌方航母图纸,使你对什么地方有屏蔽了如指掌。请你设计一个程序,根据以上信息构造通讯网络,要求信息可以在任意两条机器蛇间传递,同时为了避免干扰,通讯网络的总长度要尽可能的短。,【输入】输入数据的第一行是一个整数n(n200)表示参战的机器蛇总数。以下n行,每行两个整数xi,yi,为第i支机器蛇的战斗位置。接下来一行是一个整数m(m100)表示航母内部可能产生屏蔽的位置。最后m行,每行四个整数ai,bi,ci,di,表示线段(ai,bi)-(ci,di)处可能有屏蔽,也就是说通讯网络不能跨越这条线段。【输出】输
13、出数据应仅包括一个实数,表示建立的通讯网的最短长度,保留3位小数。如果不能成功建立通讯网,请输出-1.000。,算法分析,题目中要求信息可以在任意两条机器蛇间传递、通讯网络的总长度要尽可能的短,显然这是一个求图的最小生成树问题。这道题在构造图的过程中还涉及到一点计算几何的知识。1、判断线段相交 两条线段AB、CD,相交的充要条件是:A、B在直线CD的异侧且C、D在直线AB的异侧。也就是说从AC到AD的方向与从BC到BD的方向不同,从CA到CB的方向也与从DA到DB的方向不同。,2、套用最小生成树的经典算法求解,以机器蛇为顶点,以不受屏蔽的通信线路为边构建图,就可以直接套用最小生成树的经典算法求
14、解。由于几乎每两条机器蛇间都会有一条边,因此应选用Prim算法。设const maxn=200;oo=2000000000;机器蛇数的上限和无穷大type TPoint=record 坐标 x,y:longint;end;var s,w1,w2:array1.maxn of TPoint;机器蛇的坐标和屏蔽线的坐标 n,m,i,j,k:integer;ba:array1.maxn of boolean;机器蛇的访问标志 d:array1.maxn of longint;di以机器蛇i为头的最短边长 min:longint;ans:double;,function cp(p1,p2,p:TPoi
15、nt):integer;计算矢量PP1*PP2 var v:longint;begin v:=(p1.x-p.x)*(p2.y-p.y)-(p1.y-p.y)*(p2.x-p.x);if v=0 then cp:=0 else if v0 then cp:=1 else cp:=-1;end;cpfunction dist(a,b:integer):longint;计算第a条机器蛇和第b条机器蛇间的距离,若ab之间有屏蔽,则距离设为无穷大 var i:integer;begin dist:=oo;for i:=1 to m do 如果a到b穿过第i个屏蔽,则返回无穷大 if(cp(w1i,w2
16、i,sa)*cp(w1i,w2i,sb)=-1)and(cp(sa,sb,w1i)*cp(sa,sb,w2i)=-1)then exit;dist:=sqr(sa.x-sb.x)+sqr(sa.y-sb.y);end;dist,begin read(n);读入数据 for i:=1 to n do with si do read(x,y);read(m);for i:=1 to m do read(w1i.x,w1i.y,w2i.x,w2i.y);用Prim算法求最小生成树 fillchar(ba,sizeof(ba),0);所有机器蛇未访问 for i:=2 to n do di:=oo;最
17、短边长序列初始化 d1:=0;ans:=0;从机器蛇1出发,通信网的最短长度初始化 for i:=1 to n do begin 访问n条机器蛇 min:=oo;在所有未访问的机器蛇中寻找与已访问的机器蛇相连且具有最短边长的机器蛇k for j:=1 to n do if not baj and(djmin)then begin k:=j;min:=dj;end;then if min=oo then begin ans:=-1;break;end;then若这样的机器蛇不存在,则无解退出 ans:=ans+sqrt(min);bak:=true;最短边长计入通信网,机器蛇k已访问 for j:=1 to n do 机器蛇k出发的所有不受屏蔽的边中,寻找边长最短的(k,j)begin min:=dist(k,j);if mindj then dj:=min;end;forend;for writeln(ans:0:3);输出通信网的最短长度end.main,
链接地址:https://www.31ppt.com/p-5715923.html