对于图论这个专题,以问题为导向,进行学习,主要探究了如下问题:
1)可达矩阵的计算
2)邻接矩阵和关联矩阵的转换
3)图的连通性的计算
4)最小生成树的计算
5)Euler图和hamilton图的判断
下面,我们具体分析每一个问题:
matlab实现代码:
function P = dgraf( A )
%A为图的邻接矩阵
%P为图的可达矩阵
n=size(A,1);
P=A;
for i=2:n
P=P+A^i;
end
P(P~=0)=1;
P;
end
4)应用举例:
A=[0 1 1 1;1 0 1 1;1 1 0 1;1 1 10];
P=dgraf(A);
P=[1 1 1 1;1 1 1 1;1 1 1 1;1 1 1 1];
function W = incandadf( F,f )
%仅适用于无向图
%W是输出矩阵
%F是输入矩阵
%f=0时,表示邻接矩阵转关联矩阵,f=1表示关联矩阵转邻接矩阵
if f==0
m=sum(sum(F))/2;
n=size(F,1);
W=zeros(n,m);
k=1;
for i=1:n
for j=i:n
if F(i,j)~=0
W(i,k)=1;
W(j,k)=1;
k=k+1;
end
end
end
elseif f==1
m=size(F,2);
n=size(F,1);
W=zeros(n,n);
for i=1:m
a=find(F(:,i)~=0);
W(a(1),a(2))=1;
W(a(2),a(1))=1;
end
else
fprintf('f error');
end
W;
end
function W = mattransf( F,f )
%仅适用于有向图
%W是输出矩阵
%F是输入矩阵
%f=0时,表示邻接矩阵转关联矩阵,f=1表示关联矩阵转邻接矩阵
if f==0
m=sum(sum(F));
n=size(F,1);
W=zeros(n,m);
k=1;
for i=1:n
for j=1:n
if F(i,j)~=0
W(i,k)=1;
W(j,k)=-1;
k=k+1;
end
end
end
elseif f==1
m=size(F,2);
n=size(F,1);
W=zeros(n,n);
for i=1:m
a=find(F(:,i)~=0);
if F(a(1),i)==1
W(a(1),a(2))=1;
else
W(a(2),a(1))=1;
end
end
else
fprintf('f error');
end
W;
end
3)应用举例:
F=[0 1 1 1;1 0 1 1;1 1 0 1;1 1 10];
W=incandadf(F,0);
W=[1 1 1 0 0 0
1 0 0 1 1 0
0 1 0 1 0 1
0 0 1 0 1 1];
W1=incandadf(W,1);
W1=[0 1 1 1
1 0 1 1
1 1 0 1
1 1 1 0];
function [S,Q] = concom( G )
%图的连通性计算
%G表示图的邻接矩阵
%S表示顶点所分的块数
%Q表示每个顶点所在的块号
n=size(G,1);
m=sum(sum(G))/2;
S=0;
j=1;
C=1;
Q=zeros(n,1);
for i=1:n
for j=(i+1):n
if G(i,j)==1
if Q(i)==Q(j)
if Q(i)==0
Q(i)=C;
Q(j)=C;
C=C+1;
S=S+1;
end
else
if Q(i)==0
Q(i)=Q(j);
elseif Q(j)==0
Q(j)=Q(i);
else
for k=1:n
if Q(k)==Q(i)
Q(k)=Q(j);
end
end
S=S-1;
end
end
end
end
end
S;
Q;
end
3)应用举例:
G=[0 1 0 0;1 0 0 0;0 0 0 1;0 0 1 0];
[S,Q]=concom(G)
S = 2;
Q =[1 1 2 2];
matlab实现代码:
3)Matlab代码:
function [MST,weight] = Kruskal( W )
n=length(W);
T=zeros(n);
W2=W;
for i=1:n
for j=1:n
if W(i,j)==inf
W2(i,j)=0;
end
end
end
m=((nnz(W2))/2);
j=0;
for i=1:m
if j<(n-1)
minw=inf;
a=0;
b=0;
for k=1:n
for s=(k+1):n
if W(k,s)<=minw
minw=W(k,s);
a=k;
b=s;
end
end
end
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)<P(2,y)
for s=(y+1):m
if P(1,s)==P(2,y)
P(1,s)=P(1,y);
elseif P(2,s)==P(2,y)
P(2,s)=P(1,y);
end
end
P(2,y)=P(1,y);
elseif P(2,y)<P(1,y)
for s=(y+1):m
if P(1,s)==P(1,y)
P(1,s)=P(2,y);
elseif P(2,s)==P(1,y)
P(2,s)=P(2,y);
end
end
elseif (P(1,y)+P(2,y))~=0
f=1;
break;
end
end
if f==1
T(a,b)=0;
T(b,a)=0;
else
j=j+1;
end
W(a,b)=inf;
else
MST=T;
dianshu=n
fprintf('图的最小生成树的权邻接矩阵为:');
for i = 1:n
for j = 1:n
if MST(i,j)==inf
MST(i,j)=0;
end
end
end
MST;
weight=sum(sum(MST))/2;
break;
end
end
if j<(n-1)
fprintf('该图没有最小生成树!')
end
End
function [T,c] = Primf( a )
%Prim算法求最小生成树
%a表示权值矩阵
%c表示生成树的权和
%T表示生成树的边的集合
l=length(a);
a(a==0)=inf;
k=1:l;
listV(k)=0;
listV(1)=1;
e=1;
while(e<l)
min=inf;
for i=1:l
if listV(i)==1
for j=1:l
if listV(j)==0 && min>a(i,j)
min=a(i,j);
b=a(i,j);
s=i;
d=j;
end
end
end
end
listV(d)=1;
distance(e)=b;
source(e)=s;
destination(e)=d;
e=e+1;
end
T=[source;destination];
for g=1:e-1
c(g)=a(T(1,g),T(2,g));
end
c;
end
4)应用举例:
a(1,:)=[0 1 8 5 3 7 4];
a(2,:)=[zeros(1,2) 6 Inf 10 Inf 7];
a(3,:)=[zeros(1,3) 2 Inf Inf 9];
a(4,:)=[zeros(1,4) 4 5 6];
a(5,:)=[zeros(1,5) 9 10];
a(6,:)=[zeros(1,6) Inf];
a(7,:)=[zeros(1,7)];
a=a+a’;
[T,w]=Kruskal_1(a)
T = 0 1 0 0 3 0 4
1 0 0 0 0 0 0
0 0 0 2 0 0 0
0 0 2 0 4 5 0
3 0 0 4 0 0 0
0 0 0 5 0 0 0
4 0 0 0 0 0 0
w = 19;
a=[0 5 3 7 Inf;5 0 8 Inf 4;3 8 0 1 6;7 Inf 1 0 2;inf 4 6 2 0];
[T,c]=Primf(a)
T = 1 3 4 5
3 4 5 2
c = 3 1 2 4
function [T c] = Fleuf1( d )
%d表示图的权值矩阵
%T表示边的集合
%c表示权重和
n=length(d);
b=d;
b(b==inf)=0;
b(b~=0)=1;
m=0;
a=sum(b);
eds=sum(a)/2;
ed=zeros(2,eds);
vexs=zeros(1,eds+1);
matr=b;
for i=1:n
if mod(a(i),2)==1
m=m+1;
end
end
if m~=0
fprintf('no');
T=0;
c=0;
end
if m==0
vet=1;
flag=0;
t1=find(matr(vet,:)==1);
for ii=1:length(t1)
ed(:,1)=[vet,t1(ii)];
vexs(1,1)=vet;
vexs(1,2)=t1(ii);
matr(vexs(1,2),vexs(1,1))=0;
flagg=1;
tem=1;
while flagg
[flagg ed]=edf(matr,eds,vexs,ed,tem);
tem=tem+1;
if ed(1,eds)~=0 && ed(2,eds)~=0
T=ed;
T(2,eds)=1;
c=0;
for g=1:eds
c=c+d(T(1,g),T(2,g));
end
flagg=0;
break;
end
end
end
end
end
function [ flag ed ] = edf( matr,eds,vexs,ed,tem )
flag=1;
for i=2:eds
[dvex f]=flecvexf(matr,i,vexs,eds,ed,tem);
if f==1
flag=0;
break;
end
if dvex~=0
ed(:,i)=[vexs(1,i) dvex];
vexs(1,i+1)=dvex;
matr(vexs(1,i+1),vexs(1,i))=0;
else
break;
end
end
end
function [dvex f] = flecvexf(matr,i,vexs,eds,ed,temp)
f=0;
edd=find(matr(vexs(1,i),:)==1);
dvex=0;
dvex1=[];
ded=[];
if length(edd)==1
dvex=edd;
else
dd=1;
dd1=0;
kkk=0;
for kk=1:length(edd)
m1=find(vexs==edd(kk));
if sum(m1)==0
dvex1(dd)=edd(kk);
dd=dd+1;
ddl=1;
else
kkk=kkk+1;
end
end
if kkk==length(edd)
tem=vexs(1,i)*ones(1,kkk);
edd1=[tem;edd];
for l1=1:kkk
lt=0;
ddd=1;
for l2=1:eds
if edd1(1:2,l1)==ed(1:2,l2)
lt=lt+1;
end
end
if lt==0
ded(ddd)=edd(l1);
ddd=ddd+1;
end
end
end
if temp<=length(dvex1)
dvex=dvex1(temp);
elseif temp>length(dvex1)&&temp<=length(ded)
dvex=ded(temp);
else
f=1;
end
end
end
4)应用举例:
d=[0 1 0 1;1 0 1 0;0 1 0 1;1 0 1 0];
[T c]=Fleuf1(d)
T = 1 4 3 4
4 3 2 1
c = 4;
参考文献:
[1]李工农.运筹学基础及其MATLAB应用.北京:清华大学出版社,2016
[2]王健,赵国生.MATLAB数学建模与仿真.北京:清华大学出版社,2016
[3]王海英.图论算法及其MATLAB实现.北京:北京航空航天大学出版社,2010