用matlab实现Dijkstra算法(最短路问题)

用matlab实现Dijkstra算法(最短路问题)


首先本文设计了两种输入方式,可直接输入连接节点构成的矩阵,W(i,j)表示从i点到j点的路径权重;也可以输入各节点的子节点及对应权重,采用元胞结构,可以更方便输入。
注意在使用时注释掉另一种输入方式

这是运行结果: 在这里插入图片描述
另外在这里也简单将从初始点到目标点的最短路径输出了一下

在这里插入图片描述

clc;
clear;
%输入节点个数
n=9;
%输入目标终点的下标
m=8;
%到目标终点的反向路径
path=zeros(1,n);
path(1)=m;
%***********************************************************************************************
%直接输入有向图或无向图W
% W=[0 6 3 1 inf inf inf inf inf;inf 0 inf inf 1 inf inf  inf inf;inf 2 0 2 inf inf inf inf inf;
%     inf inf inf 0 inf 10 inf inf inf;inf inf inf 6 0 4 3 6 inf;inf inf inf inf 10 0 2 inf inf;
%     inf inf inf inf inf inf 0 4 inf;inf inf inf inf inf inf inf 0 inf;inf inf inf inf 2 inf inf 3 0];
% W=[0 6 3 1 inf inf inf inf inf;6 0 2 inf 1 inf inf  inf inf;3 2 0 2 inf inf inf inf inf;
%     1 inf 2 0 6 10 inf inf inf;inf 1 inf 6 0 4 3 6 2;inf inf inf 10 4 0 2 inf inf;
%     inf inf inf inf 3 2 0 4 inf;inf inf inf inf 6 inf 4 0 3;inf inf inf inf 2 inf inf 3 0];
% W=[0 2 inf 8 inf inf inf inf inf inf inf;inf 0 inf 6 1 inf inf inf inf inf inf;
%     1 inf 0 inf inf inf 9 inf inf inf inf;inf inf 7 0 inf inf inf inf inf inf inf;
%     inf inf inf 5 0 inf inf inf 1 inf inf;inf inf inf 1 3 0 4 inf inf inf inf;
%     inf inf inf  2 inf inf 0 inf 3 1 inf;inf inf inf inf 2 inf inf 0 inf inf 9;
%     inf inf inf inf inf 6 inf 7 0 inf inf;inf inf inf inf inf inf inf inf 1 0 4;
%     inf inf inf inf inf inf inf inf 2 inf 0];
%***********************************************************************************************
%通过输入子节点下标与权值产生矩阵W
V{1,1}=[2 3 4;6 3 1];V{1,2}=[5;1];V{1,3}=[2 4;2 2];V{1,4}=[6;10];V{1,5}=[4 6 7 8;6 4 3 6];
V{1,6}=[5 7;10 2];V{1,7}=[8;4];V{1,8}=[];V{1,9}=[5 8;2 3];
W=zeros(n);
for i=1:n     %生成对角线元素为零,其他元素为inf的初始W矩阵
    for j=i:n
        if (i==j)
            continue;
        end
        W(i,j)=inf;
    end
end
for i=1:n     %通过输入的子节点下标与权值产生最终W矩阵
    if (size(V{1,i})==0)
        continue;
    end
    for j=1:size(V{1,i},2)
        W(i,V{1,i}(1,j))=V{1,i}(2,j);
    end
end
%**********************************************************************************************
%定义已是P标号节点的集合S;P向量与T向量存v1到各点的权值;La向量存各节点的父节点下标
S=zeros(1,n);P=S;
for i=2:n
    P(i)=inf;
end
S(1)=1;T=P;La=P;
k=1;  %最新P节点下标
while(1)  %最外层循环,不断循环Dijkstra算法的二三步
    for i=1:n   %第二步
        if (W(k,i)~=0 && W(k,i)~=inf && S(i)~=1)  %满足此条件允许更新权值
            if(P(k)+W(k,i)<T(i))
                T(i)=P(k)+W(k,i);   %更新第i节点的T值
                La(i)=k;            %更新第i节点的父节点下标
            end
        end
    end
    for i=1:n   %将T中已经存在P中的对应权值变成无穷,取最小T时不参与运算
        if (S(i)~=0)
            T(i)=inf;
        end
    end
    [TW,k]=min(T);  %找到当前T标号中最小权值与下标,进行第三步
    if(TW==inf)      %循环终止条件
        break;
    end
    P(k)=TW;        %更新P节点下标及权重
    S(k)=1;         %更新P标号节点的集合
end
%输出第一点到目标终点的最短路径
i=1;
while(m~=0)
    i=i+1;
    path(i)=La(m);
    m=La(m);
end
fprintf('从V1到V%d的最短路径为:\n',path(1));
while(1)
    fprintf('V%d',path(i-1));
    i=i-1;
    if(i==1)      %循环终止条件
        fprintf('\n');
        break;
    end
    fprintf('->');
end

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值