Maylab图论

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%计算最小费用

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值