【最短路径】Dijkstra(迪杰斯特拉)算法理解

书上对Dijkstra算法的解释:

Matlab源码:

function [l, z] = Dijkstra(w, n0)
% w为邻接矩阵,无边相连记为无穷大
% n0为初始顶点的编号
n=size(w,1); %获取顶点个数
V=1:n;
w0=w(n0,:);   %获取初始顶点的邻近边
   
%赋初值
l(1:n) = w0;
z(1:n) = ones(n,1)*n0;

s=[];    %顶点集
s(1)=n0; %加入初始顶点
u=s(1);
k=1;     %顶点集中现有顶点的个数

while k<n
   % 更新 l(v) 和 z(v)
   nodeset = setdiff(V, s);
   z(nodeset(l(nodeset) > l(u) + w(u, nodeset))) = u;
   l(nodeset) = min(l(nodeset), l(u) + w(u, nodeset));
    
   %求v*
   [val, index]=min(l(nodeset));   
   u=nodeset(index);
   s(k+1)=u;
   k=k+1;
end


 看了几遍后还是不懂,于是打算查阅资料搞懂了这个算法

假设有一张这样的图G,要求从u1到其余定点的最短路径

首先列出一张u1到其余顶点的路径表,用T表示已找出最短路径,F表示未找出,初始值均W为 F 。dis表示u1到其余顶点的路径,初始值均为inf。

第一次迭代用u1为中间点,即直接判断与u1相邻的点为u2,u3,u4。

u1到u2为2<inf,需要更新。

u1到u3为1<inf,需要更新。

u1到u4为8<inf,需要更新。

同时更新u1为T

第二次迭代用u2作为中间点,与u2相邻的顶点有u4,u5。

u2到u4为6,u2到u5为1

(注意T/F为T的点不需要重复计算,因为已经是最短了)

u1到u4的路径为2+6=8=8,不需要更新。

u1到u5路径为2+1=3<inf,需要更新。

迭代结束更新列表,此时u1到u2找到最短路,更新为T。

 

第三次迭代以u3作为中间点,与u3相邻的点有u4,u7。

u3到u4为7,u3到u7为9。

u1到u4:1+7=8=8,不需要更新。

u1到u7:1+9=10<inf,需要更新。

迭代结束更新列表,此时u1到u3找到最短路,更新为T。

第四次迭代以u4作为中间点,与u4相邻的点有u2,u3,u5,u6,u7

u4到u2为6,u4到u3为7,u4到u5为5,u4到u6为1,u4到u7为2

(注意T/F为T的点不需要重复计算,因为已经是最短了)

u1到u2为8+6=14>2,不需要更新。

u1到u3为8+7=15>1,不需要更新。

u1到u5为8+5=13>3,不需要更新。

u1到u6为8+1=9<inf,需要更新。

u1到u7为8+2=10=10,不需要更新。

迭代结束更新列表,此时u1到u4找到最短路,更新为T。

 第五次迭代以u5作为中间点,与u5相邻的点有u2,u4,u6,u8。

u5到u2为1,u5到u4为5,u5到u6为3,u5到u8为9。

(注意T/F为T的点不需要重复计算,因为已经是最短了)

u1到u2为3+1=4>2,不需要更新。

u1到u4为3+5=8=8,不需要更新。

u1到u6为3+3=6<9,需要更新。

u1到u8为3+9=12<inf,需要更新。

迭代结束更新列表,此时u1到u5找到最短路,更新为T。

 第六次迭代以u6作为中间点,与u6相邻的点有u4,u5,u7,u8。

u6到u4为1,u6到u5为3,u6到u7为4,u6到u8为6。

(注意T/F为T的点不需要重复计算,因为已经是最短了)

u1到u4为6+1=7<8,需要更新。

u1到u5为6+3=9>3,不需要更新。

u1到u7为6+4=10>9,不需要更新。

u1到u8为6+6=12=12,不需要更新。

(特别注意,这里u4更新了,也就是之前的10不是最短路径,需要更改为9再进行一次迭代刷新,所以需要返回第四次迭代检查)

迭代结束更新列表,此时u1到u6找到最短路,更新为T。

 --------------------------------------------------------------------------------------------------------------------------------

(返回第四次迭代检查)以u4作为中间点,与u4相邻的点有u2,u3,u5,u6,u7

u4到u2为6,u4到u3为7,u4到u5为5,u4到u6为1,u4到u7为2

(注意T/F为T的点不需要重复计算,因为已经是最短了)

u1到u2为7+6=13>2,不需要更新。

u1到u3为7+7=14>1,不需要更新。

u1到u5为7+5=12>3,不需要更新。

u1到u6为7+1=8>6,不需要更新。

u1到u7为7+2=9<10,需要更新。(u7的值需要更新,但是这里第七次以u7为中间点的迭代还未开始,所以不需要返回u7迭代)

此时再更新列表

 --------------------------------------------------------------------------------------------------------------------------------

 第七次迭代以u7作为中间点,与u7相邻的点有u3,u4,u6,u8。

u7到u3为9,u7到u4为2,u7到u8为4,u7到u8为3

(注意T/F为T的点不需要重复计算,因为已经是最短了)

u1到u3为10+9=19>1,不需要更新。

u1到u4为10+2=12>8,不需要更新。

u1到u6为10+3=13>12,不需要更新。

u1到u8为10+3=13>12,不需要更新。

迭代结束更新列表,此时u1到u7找到最短路,更新为T。

 第八次迭代以u8作为中间点,与u8相邻的点有u5,u6,u7。

u8到u5为9,u8到u6为6,u8到u7为3。

(注意T/F为T的点不需要重复计算,因为已经是最短了)

u1到u5为12+9=21>1,不需要更新。

u1到u6为12+6=18>6,不需要更新。

u1到u7为12+3=15>9,不需要更新。

迭代结束更新列表,此时u1到u8找到最短路,更新为T。

 

 此时T/F均为T,u1到其余顶点的最短路径找到,即为0 2 1 7 3 6 9 12。

此即为所求。

Dijkstra(迪杰斯特拉)算法主要是依次选择节点进行迭代,当发现前面的节点最短路径有更新时,需要返回那次迭代刷新数据,如果返回的迭代中又刷新了最短路径,则需要在返回的迭代中继续返回那次迭代,以此往返,知道返回的迭代不需要更新时就可终止,最终当所有的最短路径都找到时,结束迭代,得出最短路径。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会C++的Mr.Li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值