Dijkstra求最短路径MATLAB

Dijkstra算法是解决单源最短路径问题的一种经典算法,用于求解从一个固定源点到图中所有其他节点的最短路径。
算法步骤如下:

1.创建一个空的距离数组 distance,用于记录源点到各个节点的当前估计最短路径值。
2.将源点的距离值初始化为0,将所有其他节点的距离值初始化为无穷大。
3.创建一个空的已访问集合 ,用于记录已经找到最短路径的节点。
4.重复以下步骤,直到所有节点都被访问:
a. 从未访问过的节点中选择一个距离值最小的节点,将其标记为已访问。
b. 更新与该节点相邻的未访问节点的距离值,如果通过该节点到达这些节点的路径距离比当前记录的最短路径值要短,则更新最短路径值。
5.最终,所有节点的最短路径值记录在一个 数组中。

Dijkstra算法的伪代码表示如下:
输入: 图G, 源点s
输出: 源点s到图G中所有其他节点的最短路径

初始化:
1. 创建距离数组 ,将源点s的距离值设为0,将其他节点的距离值设为无穷大。
2. 创建空的已访问集合 。

while 未访问的节点非空:
3. 选取距离值最小的未访问节点 u,将其标记为已访问。
4. 遍历节点 u 的所有邻居节点 v:
     - 如果通过节点 u 到达节点 v 的路径距离更短,则更新最短路径值 distance[v]。
5. 标记节点 u 已访问。

返回距离数组 

Dijkstra算法保证在无负权边的情况下找到源点到图中所有其他节点的最短路径。如果某些节点无法通过路径到达,则其最短路径值将保持为无穷大即inf

原理

本文修改了该文章一些地方,并详细标注和补充

如有下方距离矩阵:

  Inf    50   Inf    40    25    10;
    50   Inf    15    20   Inf    25;
   Inf    15   Inf    10    20   Inf;
    40    20    10   Inf    10    25;
    25   Inf    20    10   Inf    55;
    10    25   Inf    25    55   Inf

程序: 

clc,clear all
a=[  Inf    50   Inf    40    25    10;
    50   Inf    15    20   Inf    25;
   Inf    15   Inf    10    20   Inf;
    40    20    10   Inf    10    25;
    25   Inf    20    10   Inf    55;
    10    25   Inf    25    55   Inf];                                                                 
pb(1:length(a))=0;
pb(1)=1;  %当一个点已经求出到原点的最短距离时,其下标i对应的pb(i)赋1,即0-1变量
index1=1; %标号顶点顺序
index2=ones(1,length(a)); %~索引
d(1:length(a))=inf;d(1)=0;  %存放由始点到第i点最短通路的值
temp=1;  %表示起始节点为1

while sum(pb)<length(a)  %看是否所有的点都标记为P标号
tb=find(pb==0); %找到标号为0的所有点,即找到还没有存入的点
d(tb)=min(d(tb),d(temp)+a(temp,tb));
%d(temp) 表示起点到当前访问节点 temp 的最短路径值。a(temp, tb) 表示当前访问节点 temp 到点集 tb 所有点的距离。 d(tb) 是存放从起点到每个节点的最短路径值的向量。通过计算 d(temp) + a(temp, tb),得到起点经过当前访问节点 temp 到达点集 tb 的距离。然后将这个值与 d(tb) 中原先存储的最短路径进行比较,选取较小的值用于更新最短路径
tmpb=find(d(tb)==min(d(tb)));  %求d[tb]序列最小值的下标
temp=tb(tmpb(1));%可能有多条路径同时到达最小值,却其中一个,temp也从原点变为下一个点
pb(temp)=1;%找到最小路径的表对应的pb(i)=1
index1=[index1,temp];  %存放存入集合的顺序
temp2=find(d(index1)==d(temp)-a(temp,index1));
index2(temp)=index1(temp2(1)); %记录标号索引
end
d, index1, index2

输出结果:


d =

     0    35    45    35    25    10


index1 =

     1     6     5     2     4     3


index2 =

     1     6     5     6     1     1

罚函数法:

function [mydistance,mypath]=mydijkstra(a,sb,db);
% 输入: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);

调用方法:

clc,clear all;
a = [ Inf    50   Inf    40    25    10
    50   Inf    15    20   Inf    25
   Inf    15   Inf    10    20   Inf
    40    20    10   Inf    10    25
    25   Inf    20    10   Inf    55
    10    25   Inf    25    55   Inf];%可换成自己的距离矩阵
sb = 1;  % 起点是节点1
db = 3;  % 终点是节点3

[mydistance, mypath] = mydijkstra(a, sb, db);

disp(['最短路径长度: ' num2str(mydistance)]);
disp(['最短路径: ' num2str(mypath)]);

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值