Matlab最小生成树

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数学建模——Matlab中求解最小生成树

关键词:Matlab、最小生成树、破圈法、避圈法、运筹学

要求:选择一道编程题自己独立完成,必须自己编写源代码,不能从网上下载。先编写算法的通用程序,然后以例子运行,论文内容包括程序代码、程序说明、例子运行结果,最终程序文件连同论文一起发至e-mail,便于老师运行程序是否正确。编程使用C或MATLAB。

选择题目:编写实现生成树、最小生成树的程序(包括避圈法、破圈法)。

题目分析:本题要求编写实现生成树、最小生成树的程序,首先来了解一下关于关于生成树的概念:

1、树的概念:

树是无向图的特殊情况,即对于一个N个节点的无向图,其中只有N-1条边,且图中任意两点间有且只有一条路径,即图中不存在环,这样的图称为树。2、生成树的概念:

对于一个无向连通图G=(V,E),其中V代表顶点,E代表边,对它做一次遍历,每个节点经过一次,那么图中的N个节点再加上遍历过程中经过的N-1条边所构成的子图就是图G的一个生成树。

3、最小生成树的概念:

对于一个无向连通图G=(V,E),给它的每条边(u,v)赋一个权值w(u,v)。若图G 的生成树不止一个,那么其中包含的N-1条边的权值之和的最小的生成树就是图G的最小生成树。

4、关于运筹学中最小生成树有2种不错的算法,即避圈法和破圈法,下面来看一下求解最小生成树的算法:

先看一下图示法表示的最小生成树:

<1>避圈法求解上面无向带权连通图的基本步骤是:

每步从未选的边中选取边e,使它与已选边不构成圈,且e是未选边中的最小权

边,直到选够n-1条边为止。

<2>破圈法基本思想如下:

(1) 每次从图中选取任意一个圈, 然后去掉该圈中权值最大的边(如果存在多条相同权值的最大边,可以任意选择一条去掉即可) 使之不构成圈.

(2) 重复上述过程. 直到图中不再含圈且所有顶点均包含在图中为止, 就构成最小生成树.

它的算法图解如下:

5、我们在用matlab程序求解最小生成树的时候需要用到无向图的邻接矩阵,首先来了解一下邻接矩阵的概念。

邻接矩阵(Adjacency Matrix):是表示顶点之间相邻关系的矩阵。设G=(V,E)是

一个图,其中V={v1,v2,…,vn}。G的邻接矩阵是一个具有下列性质的n阶方阵:①对无向图而言,邻接矩阵一定是对称的,而且对角线一定为零,有向图则不一定如此。

②在无向图中,任一顶点i的度为第i列所有元素的和,在有向图中顶点i的出度为第i行所有元素的和,而入度为第i列所有元素的和。

③用邻接矩阵法表示图共需要n^2个空间,由于无向图的邻接矩阵一定具有对称关系,所以扣除对角线为零外,仅需要存储上三角形或下三角形的数据即可,因此仅需要n(n-1)/2个空间。

看一个例子:

上面的邻接矩阵是带权邻接矩阵,有两种表示方法,我们往往只使用第一种,它的正对角线上全部是0,方便在程序中求解。

编程内容:

有了以上的数学基础,就可以在Matlab中编写适当的程序来求解无向带权图的最小生成树。下面先用避圈法实现求解,代码中有详细的解析说明:

<1>避圈法Matlab程序代码:

%编程工具Matlab;

%这是一个通过避圈法求解连通带权图的最小生成树的程序.

n=input('请输入图的顶点数目:n= ')

W=input('请输入图的加权邻接矩阵:[W(1,1),..,W(1,n);..;W(n,1),..,W(n,n)]=')

%用W(i,i)="inf" 代替 "=0"

%准备工作

T=zeros(n); %最小生成树的加权邻接矩阵

WW=W;

for i=1:n

for j=1:n

if W(i,j)==inf WW(i,j)=0;

end

end

end

m=((nnz(WW))/2); %图的边线的数目

j=0; %最小生成树的边线的数目

%主要步骤

for i=1:m %被选择边线的数目

if j<(n-1) %算法的终止条件是 |E|=|V|-1.

%步骤0: 挑选出权值最小的边 W(a,b)

min=inf; a=0; b=0;

for k=1:n

for l=(k+1):n

if W(k,l)<=min min=W(k,l); a=k; b=l; end

end

end

%步骤0 结束

%步骤1

%T=T+e(a,b)

T(a,b)=W(a,b); T(b,a)=W(a,b);

%检查是否有环的出现

f=0; %没有环的出现

P=zeros(2,m); y=0;

for i=1:n

for v=(i+1):n

if T(i,v)~=0 y=y+1; P(1,y)=i; P(2,y)=v; end

end

end

for y=1:m

if P(1,y)

for l=(y+1):m

if P(1,l)==P(2,y) P(1,l)=P(1,y);

elseif P(2,l)==P(2,y) P(2,l)=P(1,y);

end

end

P(2,y)=P(1,y);

elseif P(2,y)

for l=(y+1):m

if P(1,l)==P(1,y) P(1,l)=P(2,y);

elseif P(2,l)==P(1,y) P(2,l)=P(2,y);

end

end

P(1,y)=P(2,y);

elseif (P(1,y)+P(2,y))~=0 f=1; %出现一个环

break

相关文档
最新文档