MATLAB实现Dijkstra最短路算法

1.算法作用及适用范围

MATLAB实现Dijkstra最短路算法_第1张图片
源点与汇点为图中存在边的两个顶点;
费用即为权值;(如有不便,可以在草稿纸上画出来并标明权值)
迪克斯特拉算法解决无向加权图中最短路问题,所有的权为正。

1.1推理描述

需求:求从①顶点到④顶点的最短路径
分析:(权值为到①的权值和)
寻找第一近的顶点;假设从①顶点开始(后文简称1);找到一个距离①最近的顶点,这些顶点分别为权值为4的②和权值为2的⑥;所以⑥是最靠近①的顶点。
寻找第二近的顶点;查看所有以①为起点到集合{①,⑥}中的顶点的最短路;接着的边以{①,⑥}中的边为起点,寻找下一个最短的路的顶点(不在此集合中);此时①可以为新起点、⑥也可以为新起点;到①的最近的顶点为②,权值为4,到⑥的最近的顶点为⑤,权值为2+3=5;所以,下一个 靠近集合{①,⑥}最近的顶点为②,权值为4……
后面的思路同上;直到找到了④停止;

2.算法思想及代码

2.1算法思想

在Dijkstra算法中,假设起始点为a,u为添加进Sk-1成为Sk的顶点;每一步中选择添加进集合的顶点u,都是一次最优选择,使之成为贪婪算法(下面简单的阐述一下这个贪婪算法得到的总是最优解)
设v是不属于集合Sk的一个顶点,更新v的标记,注意Lk(V)是包含Sk中的顶点的从a到v的最短通路的长度,接下来完成更新步骤:只包含Sk中顶点的从a到v的最短通路,要么是只包含Sk-1中的顶点(即不包括u在内的特殊顶点)的从a到v的最短通路,要么是在第k-1阶段加上边(u,v)的从a到v的最短通路。

Lk(a,v)=min{Lk-1(a,v),Lk-1(a,u)+w(u,v)}

w(u,v)是以u、v为端点的边的长度(权值)。这个过程依次迭代:依次添加顶点,知道目标点被添加后停止。

2.2代码及注释

function [d,path]=Dijkstra2(A,start,tail)
%Dijkstra算法
%d为每个点对应的最短距离行向量
%path保存该点的上一个顶点
%若输入为矩阵A;默认初始点为第一个顶点
%若输入为矩阵A,start;则以start为初始顶点,求各个顶点的最短路径
%若输入为矩阵A,start,tail,则计算从start开始到tail的最短路

%初始化部分
n=length(A);
d(1:n)=0;%保存第i个点到其实节点的最短路径
pb(1:n)=0;%若第i个点已经找到最短路,则pb(i)=1;,否则pb(i)==0
path(1:n)=0;%保存第i个点的上一个节点
if nargin == 1
    flag = 1;
elseif nargin == 2
    flag = 2;
elseif nargin == 3
    flag = 3;
end
%Dijkstra算法开始
if flag == 1
    pb(1)=1;%保存初始点
    path(1)=0;
else
    pb(start)=1;
    path(start)=0;
end
while sum(pb)<n
    fb=find(pb);
    tb=find(pb==0);
    minn = Inf;
    for i=1:length(fb)
        for j = 1:length(tb)
            total = d(fb(i)) + A(fb(i),tb(j));
            if(total < minn)
                minn = total;
                last=fb(i);
                new=tb(j);
            end
        end
    end
    d(new) = minn;
    pb(new) = 1;
    path(new) = last;
    if(flag==3 && pb(end)==1)
        fprintf('\n从%d到%d的最短距离为%d\n',start,tail,d(tail));
        break;
    else
        continue;
    end
end

2.3运行结果

输入:
MATLAB实现Dijkstra最短路算法_第2张图片
输出:
MATLAB实现Dijkstra最短路算法_第3张图片

你可能感兴趣的:(图论)