D算法

本文介绍了一种使用MATLAB高效实现Dijkstra算法的方法,通过矩阵操作替代循环,简化程序并提高效率。文章详细展示了算法的框架、代码及实验结果,验证了其正确性和实用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 概述

            D算法,即Dijkstra算法,它的作用是找出某个节点到其它节点的最短距离。本文使用MATLAB实现D算法,使整个算法非常简洁。从之前的学习中知道,MATLAB实现矩阵操作是非常高效的,所以本文尽量使用了矩阵操作来替代循环操作。这种做法一方面是提高了程序的效率,另一方面能够使程序更加简洁。但是这种做法在某些情况下也不见得是优点。首先,将一个循环程序转换为矩阵操作需要一定的时间,并且有时候比较难。其次,MATLAB的作用相当于“急先锋”,快速实现人们的想法,但是最后应用的,往往是使用C/C++。这样就会出现一些问题,这里描述两个我所遇到和想到的问题。问题一,有的时候在MATLAB中非常高效的程序转换为C/C++之后反而变慢了。这个问题来源于我之前参与的一个项目,项目中使用了聚类算法K-means。利用MATLAB中集成的函数,该聚类算法执行速度很快,但是移植到C/C++上之后却慢了很多。原因就是MATLAB中的矩阵操作其实是很高效的。问题二,大量集成的函数会增加移植的难度。这个问题是显而易见的,MATLAB能得到广泛使用与它集成的很多快捷的函数是离不开的,但是在移植的过程中这些函数可能需要自己重写,这就增加了移植的难度。

2 算法框架

            D算法的算法框架如图1所示。

图1 D算法实现框架

3 程序代码

3.1 源代码

% D算法实现

% 备注:本程序使用所有直连路径长度的和+1作为无穷大长度

clear all;

close all;



InData = textread('例2_3_2.txt');

Infinite = sum(sum(InData.*double((InData>=0))))/2+1;  %计算所有直接相连的路径长度+1,作为无穷大

InData = InData.*(double(InData<0).*(-1).*(Infinite))+InData.*(double(InData>=0));



Gp = uint32(zeros(1,size(InData,1)));  %保存顶点

Gpp = ones(1,size(InData,1))*Infinite;  %保存顶点相应权重

Gr = 1:size(InData,1);  %G-Gp

Grr = InData(1,:);  %与G-Gp所对应的权重

for ii = 1:size(InData,1)

    [TempMin,index] = min(Grr);

    Gp(ii) = Gr(index);

    Gpp(ii) = TempMin;

   

    % 更新,这是最关键的部分,本质上也简单,就是将每个新加入的点最为中间点,

    % 看是否会产生更近的路径。

    Gr(index) = [];

    temp = Gpp(ii)+InData(Gp(ii),:);

    temp = InData(1,:)-temp;

    temp = temp.*double((temp>0));

    temp = sum(temp,1);

    InData(1,:) = InData(1,:)-temp;

    Grr = InData(1,:);

    Grr(Gp(1:ii)) = [];

end

3.2 代码分析

            本文的正无穷也是设定的一个相对值。同时本文的代码中大量使用了矩阵运算来是程序变得精简,为了说明本文所示代码的精简程度,3.3贴出网上的一个D算法实现版本,同样是使用MATLAB。同时需要说明一点,就是为什么我会使用ii来控制循环。因为在MATLAB中,i和j又可以用来表示虚数,所以一般不会像C/C++一样用来控制循环。

3.3 一个网上寻找的D算法实现代码

function [ distance path] = Dijk( W,st,e ) 

%DIJK Summary of this function goes here 

%   W  权值矩阵   st 搜索的起点   e 搜索的终点 

n=length(W);%节点数 

D = W(st,:); 

visit= ones(1:n); visit(st)=0; 

parent = zeros(1,n);%记录每个节点的上一个节点 

 

path =[]; 

 

for i=1:n-1 

    temp = []; 

    %从起点出发,找最短距离的下一个点,每次不会重复原来的轨迹,设置visit判断节点是否访问 

    for j=1:n 

       if visit(j) 

           temp =[temp D(j)]; 

       else 

           temp =[temp inf]; 

       end 

        

    end 

     

    [value,index] = min(temp); 

    

    visit(index) = 0; 

     

    %更新 如果经过index节点,从起点到每个节点的路径长度更小,则更新,记录前趋节点,方便后面回溯循迹 

    for k=1:n 

        if D(k)>D(index)+W(index,k) 

           D(k) = D(index)+W(index,k); 

           parent(k) = index; 

        end 

    end 

     

    

end 

 

distance = D(e);%最短距离 

%回溯法  从尾部往前寻找搜索路径 

t = e; 

while t~=st && t>0 

 path =[t,path]; 

  p=parent(t);t=p; 

end 

path =[st,path];%最短路径

end

4 实验结果

4.1 输入数据说明

            为了便于MATLAB读取数据方便,原始数据中使用-1来表示正无穷。图2展示了输入的数据。

图2 输入数据

4.2 实验结果说明

            程序的运行结果如图3所示。其中Gp中保存了目的节点,Gpp中保存了需要经过的路径长度。

图3 程序运行结果

            对比图3和图4可知程序运行结果正确。

图4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值