【转载】数学建模——MATLAB寻找最短路径(Dijkstra算法和Floyd算法)

相信玩过ACM的都很熟悉最短路径问题,这里就不赘述原理和过程了,直接上代码

邻接矩阵a如下:
0 50 Inf 40 25 10
50 0 15 20 Inf 25
Inf 15 0 10 20 Inf
40 20 10 0 10 25
25 Inf 20 10 0 55
10 25 Inf 25 55 0

Dijkstra算法

function [mydistance,mypath]=mydijkstra(a,sb,db);
%寻找i,j两点最短路径
% 输入:a—邻接矩阵,a(i,j)是指i到j之间的距离,可以是有向的
% sb—起点的标号, db—终点的标号
% 输出:mydistance—最短路的距离, mypath—最短路的路径
n=size(a,1); visited(1:n) = 0;
distance(1:n) = inf; distance(sb) = 0; %起点到各顶点距离的初始化
visited(sb)=1; u=sb;  %u为最新的P标号顶点
parent(1:n) = 0; %前驱顶点的初始化
for i = 1: n-1
     id=find(visited==0); %查找未标号的顶点
     for v = id           
         if  a(u, v) + distance(u) < distance(v)
             distance(v) = distance(u) + a(u, v);  %修改标号值 
             parent(v) = u;                                    
         end            
     end
     temp=distance;
     temp(visited==1)=inf;  %已标号点的距离换成无穷
     [t, u] = min(temp);  %找标号值最小的顶点 
     visited(u) = 1;       %标记已经标号的顶点
 end
mypath = [];
if parent(db) ~= 0   %如果存在路!
    t = db; mypath = [db];
    while t ~= sb
        p = parent(t);
        mypath = [p mypath];
        t = p;      
    end
end
mydistance = distance(db);

     
     
     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
function [d,index1]=mydijkstra2(a,sb);
%从起点出发,寻找遍历所有点的最短路径
% 输入:a—邻接矩阵,a(i,j)是指i到j之间的距离,可以是有向的
% sb—起点的标号
% 输出:d—从起点开始便利所有标号的最短路距离, index1—从起点开始便利所有标号的最短路路径
%pb用来存放P标号信息 index1为标号顶点顺序 index2标号顶点索引
a(a==0)=inf;
pb(1:length(a))=0;pb(sb)=1;index1=sb;index2=ones(1,length(a));
%d用来存放最短通路的值
d(1:length(a))=inf;d(sb)=0;
temp=sb;%最新的P标号的起点
while sum(pb)<length(a)
    tb=find(pb==0);
    d(tb)=min(d(tb),d(temp)+a(temp,tb));
    tmpb=find(d(tb)==min(d(tb)));
    temp=tb(tmpb(1));%可能有多个点同时达到最小值,只取其中一个
    pb(temp)=1;
    index1=[index1,temp];
    temp2=find(d(index1)==d(temp)-a(temp,index1));
    index2(temp)=index1(temp2(1));
end
end
     
     
     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

Floyd算法

function [dist,mypath]=myfloyd(a,sb,db)
%寻找i,j两点最短路径
% 输入:a—邻接矩阵,元素(aij)是顶点i到j之间的直达距离,可以是有向的
% sb—起点的标号;db—终点的标号
% 输出:dist—最短路的距离;% mypath—最短路的路径
n=size(a,1); path=zeros(n);
for k=1:n
    for i=1:n
        for j=1:n
            if a(i,j)>a(i,k)+a(k,j)
                a(i,j)=a(i,k)+a(k,j);
                path(i,j)=k;
            end
        end
    end
end
dist=a(sb,db);
parent=path(sb,:); %从起点sb到终点db的最短路上各顶点的前驱顶点
parent(parent==0)=sb; %path中的分量为0,表示该顶点的前驱是起点
mypath=db; t=db;
while t~=sb
        p=parent(t); mypath=[p,mypath];
        t=p;
end

     
     
     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
function [path]=myfloyd2(a)
%寻找各顶点之间的最短通路
% 输入:a—邻接矩阵,元素(aij)是顶点i到j之间的直达距离,可以是有向的
% 输出:path—各顶点之间的最短通路值
n=length(a);
a(a==0)=inf;
a([1:n+1:n^2])=0; %对角线元素替换成零,Matlab中数据是逐列存储的
path=zeros(n);
for k=1:n
   for i=1:n
      for j=1:n
         if a(i,j)>a(i,k)+a(k,j)
            a(i,j)=a(i,k)+a(k,j);
            path(i,j)=k;
         end 
      end
   end
end
end
     
     
     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
        
            

你可能感兴趣的:(【转载】数学建模——MATLAB寻找最短路径(Dijkstra算法和Floyd算法))