1.Dijkstra求最短路径
road=zeros(3,3);%存有向图的邻接矩阵,自己随意输入
road(1,2)=3;road(2,3)=1;
road(road==0)=inf;
flag=zeros(1,length(road));%存遍历过的结点标记
flag(1)=1;
while sum(flag)<length(road)
fmin=inf;
j=-1;
for z=1:length(road(1,:))
if road(1,z)<fmin && flag(1,z)==0
fmin=road(1,z);
j=z;
end
end
for z=1:length(road(1,:))
if fmin==inf || road(j,z)==inf
continue;
end
if fmin+road(j,z)<road(1,z)
road(1,z)=fmin+road(j,z);
end
end
flag(j)=1;
end
2.最小生成树 prim算法
road=zeros(3,3);%存有向图的邻接矩阵,自己随意输入
road(1,2)=3;road(2,3)=1;
road(road==0)=inf;
flag=zeros(1,length(road));%存遍历过的结点标记
flag(1)=1;
for a=1:length(road(1,:))-1
fmin=inf;
i=-1;
j=-1;
for k=1:length(road(1,:))
for z=1:length(road(1,:))
if flag(1,k)==0 ||road(k,z)==inf
continue;
end
if road(k,z)<fmin
fmin=road(k,z);
i=k;
j=z;
end
end
end
if j==-1
break;
end
flag(j)=1;
fprintf("最小生成树的路径为:结点%d---->结点%d,长度为:%d \n",i,j,fmin)
end
3.图的连通性计算
%图的连通性计算
%G表示邻接矩阵
%S表示分的块数
%Q表示分的块数量
function [S,Q]=concom(G)
n=size(G,1);
S=0;
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
4.广度优先搜索算法
%广度优先搜索算法
%G表示图的邻接矩阵
%W表示图顶点的标号
function W=BFS(G)
n=size(G,1);
W=zeros(1,n);
l=0;
v=1;
al=find(G(v,:)==1);
G(v,al)=2;
G(al,v)=2;
W(al)=l+1;
S1=union(al,v);
l=l+1;
while ~isempty(G==1)
al=find(G(S1,:)==1);
t=length(S1);
d=[];
for i=1:length(al)
if al(i)/t>floor(al(i)/t)
t2=floor(al(i)/t)+1;
else
t2=floor(al(i)/t);
end
if isempty(intersect(d,t2))
d=union(d,t2);
end
end
dl=setdiff(d,S1);
if isempty(dl)
break;
else
W(dl)=l+1;
G1=G(S1,:);
G1(al)=2;
G(S1,:)=G1;
G(:,S1)=G1';
S1=union(S1,dl);
l=l+1;
end
End
5.深度优先搜索算法
%dfs算法
%G表示邻接矩阵
%W表示边的访问顺序按照数字由小到大排序
%k表示图顶点的标号
%f表示相应顶点的父亲顶点
function [W k f]=Dijkstra(G)
n=size(G,1);
W=G;
v=1;
k=zeros(1,n);
f=zeros(1,n);
b=sum(sum((W==1)));
c=sum(k==0);
d=1;
if b==0 && v==1 &&c==0
d=0;
end
k(1)=1;
j=2;
l=2;
while d
a=find(W(v,:)==1);
if isempty(a)
W(v,f(v))=l;
l=l+1;
v=f(v);
else
for i=1:length(a)
if k(a(i))==0
k(a(i))=j;
j=j+1;
W(v,a(i))=l;
l=l+1;
f(a(i))=v;
v=a(i);
break;
elseif k(a(i))~=0
W(v,a(i))=l;
l=l+1;
end
end
end
b=sum(sum((W==1)));
c=sum(k==0);
if b==0 && v==1 &&c==0
d=0;
end
end
6.求欧拉回路
function [T c]=fleuf1(d)
%注:必须保证是Euler环游,否则输出T=0,c=0
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('there is not exit Euler path.\n')
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
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
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;
dd1=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
7.哈密顿回路改良圈算法
%改良圈算法
%d 表示图的权值矩阵
%c表示最终找到的哈密顿圈
function [C,dl]=Dijkstra(d)
n=size(d,2);
C=[linspace(1,n,n),1];
C1=C;
if n>3
for v=4:n+1
for i=1:(v-3)
for j=(i+2):(v-1)
if (d(C(i),C(j))+d(C(i+1),C(j+1))<d(C(i),C(i+1))+d(C(j),C(j+1)))
C1(1:i)=C(1:i);
for k=(i+1):j
C1(k)=C(j+i+1-k);
end
C1((j+1):v)=C((j+1):v);
end
end
end
end
elseif n<=3
if n<=2
fprintf("不存在哈密顿环路");
else
fprintf("任意回路均为所求");
end
end
C=C1;
dl=0;
for i=1:n
dl=dl+d(C(i),C(i+1));
end
8.二分图最大基数匹配
%图的较大基数匹配
%W表示图的邻接矩阵
%J表示一个较大的基数匹配矩阵
function J=matgraf(W)
n=size(W,1);
J=zeros(n,n);
while sum(sum(W))~=0
a=find(W~=0);
t1=mod(a(1),n);
if t1==0
t1=n;
end
if a(1)/n>floor(a(1)/n)
t2=floor(a(1)/n)+1;
else
t2=floor(a(1)/n);
end
J(t1,t2)=1;
J(t2,t1)=1;
W(t1,:)=0;
W(:,t1)=0;
W(t2,:)=0;
W(:,t2)=0;
end
9.利用Ford--Fulkerson 标号法求最大流算法
function [f,wf,No] = fofuf(C,f1)
% 利用Ford--Fulkerson 标号法求最大流算法的MATLAB 程序代码
% f %显示最大流
% wf %显示最大流量
% No %显示标号, 由此可得最小割
% n 节点个数
% C %弧容量
n = length(C);
if nargin==1;
f=zeros(n,n);
else
f=f1;
end
No=zeros(1,n);
d=zeros(1,n);
while(1)
No(1)=n+1;
d(1)=Inf; %给发点VS标号
while(1)
pd=1; %标号过程
for i=1:n
if(No(i)) %选择一个已标号的点vi
for j=1:n
if(No(j)==0&&f(i,j)<C(i,j))%对于未标号的点vj,当vivj为非饱和弧时
No(j)=i;
d(j)=C(i,j)-f(i,j);
pd=0;
if(d(j)>d(i))
d(j)=d(i);
end
elseif(No(j)==0&&f(j,i)>0)
No(j)=-i;
d(j)=f(j,i);
pd=0;
if(d(j)>d(i))
d(j)=d(i);
end
end
end
end
end
if(No(n)||pd)
break;
end
end %若收点vt得到标号或者无法标号,则终止标号过程
if(pd)
break;
end %vt未得到标号,f以是最大流,算法终止
dvt=d(n);t=n; %进入调整过程,dvt表示调整量
while(1)
if(No(t)>0)
f(No(t),t)=f(No(t),t)+dvt; %向前弧调整
elseif(No(t)<0)
f(No(t),t)=f(No(t),t)-dvt; %向后弧调整
end
if(No(t)==1)
for i=1:n
No(i)=0;d(i)=0;
end
break
end %当t的标号为vs时,终止调整过程
t=No(t);
end
end %继续调整前一段弧上的电流f
wf=0;
for j=1:n
wf=wf+f(1,j);
end %计算最大电流量
10.最小费用最大流
function [f wf zwf]=BGf(C,b)
% function [f wf zwf]=BGf(C,b)
% 计算给定图的最小费用最大流
% C;%弧容量
% b;%弧上单位流量的费用
% f 最小费用最大流矩阵,wf 最大流量 zwf 最小费用
n=size(C,2);
wf=0;wf0=Inf; %wf表示最大流量, wf0表示预定的流量值
f=zeros(n,n); %取初始可行流f 为零流
while(1)
a=ones(n,n)*inf;
for(i=1:n)
a(i,i)=0;
end%构造有向赋权图
for(i=1:n)
for(j=1:n)
if(C(i,j)>0&f(i,j)==0)
a(i,j)=b(i,j);
elseif(C(i,j)>0&f(i,j)==C(i,j))
a(j,i)=-b(i,j);
elseif(C(i,j)>0)a(i,j)=b(i,j);
a(j,i)=-b(i,j);
end
end
end
for(i=2:n)
p(i)=Inf;s(i)=i;
end %用Ford 算法求最短路, 赋初值
for(k=1:n)
pd=1; %求有向赋权图中vs 到vt 的最短路
for(i=2:n)
for(j=1:n)
if(p(i)>p(j)+a(j,i))
p(i)=p(j)+a(j,i);s(i)=j;pd=0;
end
end
end
if(pd)
break;
end
end %求最短路的Ford 算法结束
if(p(n)==Inf)
break;
end %不存在vs 到vt 的最短路, 算法终止。 注意在求最小费用最大流时构造有向赋权图中不会含负权回路, 所以不会出现k=n
dvt=Inf;t=n; %进入调整过程, dvt 表示调整量
while(1) %计算调整量
if(a(s(t),t)>0)
dvtt=C(s(t),t)-f(s(t),t); %前向弧调整量
elseif(a(s(t),t)<0)
dvtt=f(t,s(t));
end %后向弧调整量
if(dvt>dvtt)
dvt=dvtt;
end
if(s(t)==1)
break;
end %当t 的标号为vs 时, 终止计算调整量
t=s(t);
end %继续调整前一段弧上的流f
pd=0;
if(wf+dvt>=wf0)
dvt=wf0-wf;pd=1;
end%如果最大流量大于或等于预定的流量值
t=n;
while(1) %调整过程
if(a(s(t),t)>0)
f(s(t),t)=f(s(t),t)+dvt; %前向弧调整
elseif(a(s(t),t)<0)
f(t,s(t))=f(t,s(t))-dvt;
end %后向弧调整
if(s(t)==1)
break;
end %当t 的标号为vs 时, 终止调整过程
t=s(t);end
if(pd)
break;
end%如果最大流量达到预定的流量值
wf=0;
for(j=1:n)
wf=wf+f(1,j);
end
end %计算最大流量
zwf=0;
for(i=1:n)
for(j=1:n)
zwf=zwf+b(i,j)*f(i,j);
end
end%计算最小费用