• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

matlab实现dijkstra算法多路径显示

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

如果刚接触这个算法的先找找别人的文章,我这里就不讲算法原理了,别人讲的太多了。。。
由于最近在参加数模比赛,老师给了我们一道求最短路径的题目。
分别用Dijkstra算法和Floyd算法求A到D的最短路径;
我也在网上搜索了matlab关于Dijkstra算法的程序,这是我从别人博客处获得的dijkstra代码:

function [ d,path ] = dijkstra(m,temp)
%m为权矩阵
%temp为起始点编号
n=size(m,1); %提取矩阵大小
pb(1:length(m))=0;pb(temp)=1;%求出最短路径的点为1,未求出的为0
d(1:length(m))=0;%存放各点的最短距离
path(1:length(m))=0;%存放各点最短路径的上一点标号
while sum(pb)<n %判断每一点是否都已找到最短路径
tb=find(pb==0);%找到还未找到最短路径的点
fb=find(pb);%找出已找到最短路径的点
min=inf;
for i=1:length(fb)
for j=1:length(tb)
plus=d(fb(i))+m(fb(i),tb(j)); %比较已确定的点与其相邻未确定点的距离
if((d(fb(i))+m(fb(i),tb(j)))<min)
min=d(fb(i))+m(fb(i),tb(j));
lastpoint=fb(i);
newpoint=tb(j);
end
end
end
d(newpoint)=min;
pb(newpoint)=1;
path(newpoint)=lastpoint; %最小值时的与之连接点
end
d
path
end

PS:上面这个是dijkstra算法函数,我稍加改动,主要是为了方便自己使用,主体没有变。

function DisplayPath1dijkstra(route, start, dest)
% route 路径
% start :起点
% dest : 终点
%目标路径
t=1;
o=dest;%暂存上一点,且判断何时停止
y(1,t)=o;
while o~=start
o=route(o);
t=t+1;
y(1,t)=o;
end
n=length(y); %提取矩阵大小
for k=1:n
destpath(1,k)=y(1,n+1-k);
end
destpath
end

PS:这个我依据另外一个写floyd算法的人改编的的dijkstra算法路径显示函数

m= [0,4,inf,18,7,17, 11,inf;
4,0,2, inf,6,inf,15,inf;
inf,2,0, 9, 1, 8, inf,10;
18,inf,9,0,11,1, inf, 3;
7,6, 1, 11,0,10, 9, 4 ;
17,inf,8 ,1 10,0, inf, 2;
11,15,inf,inf,9,inf,0,5 ;
inf,inf,10, 3, 4, 2, 5, 0;];
start=1;dest=4;
[ d,path ] = dijkstra(m,start);
DisplayPath1dijkstra(path, start, dest)
length=d(dest)

PS:这个是主程序,start=1代表A,D排序排到4,所以dest=4,表示从A到D

结果显示:
destpath = 1 5 8 6 4 ( 那么对应路径就是 A E H F D)
length=14

PS:到这里大家就发现了,我们只能找到一条路径,路径长度是14。上面三段程序是一个完整过程,但缺点是只能显示一条路径

!!!!!!!!接下来是本文章的重点!!!!!!!!
*
尽管C语言我学的不是很扎实,但是我还是用了结构体来完成多路径显示,出了很多bug。。。但是花了很长时间改好了。matlab中结构体有一个特点就是可以动态扩展,这样我们一旦发现了另外一条路径就可以让结构体多一组。
下面的程序是基于上面的程序我自己改进的多路径显示程序(成就感满满!)
function [x,t]=dijkstrapro(m,temp)
%m为权矩阵
%temp为起始点编号
t=1; %为最短路径数
n=size(m,1); %提取矩阵大小
x(1).pb(1:length(m))=0;x(1).pb(temp)=1;%求出最短路径的点为1,未求出的为0
x(1).d(1:length(m))=0;%存放各点的最短距离
x(1).path(1:length(m))=0;%存放各点最短路径的上一点标号
k=1;
while k<=t
while sum(x(k).pb)<n %判断每一点是否都已找到最短路径
x(k).tb=find(x(k).pb0);%找到还未找到最短路径的点
x(k).fb=find(x(k).pb);%找出已找到最短路径的点
x(k).min=inf;
for i=1:length(x(k).fb)
for j=1:length(x(k).tb)
x(k).plus=x(k).d(x(k).fb(i))+m(x(k).fb(i),x(k).tb(j)); %比较已确定的点与其相邻未确定点的距离
if(x(k).plus<x(k).min)
x(k).min=x(k).plus;
x(k).lastpoint=x(k).fb(i);
x(k).newpoint=x(k).tb(j);
end
end
end
for i=1:length(x(k).fb)
for j=1:length(x(k).tb)
x(k).plus=x(k).d(x(k).fb(i))+m(x(k).fb(i),x(k).tb(j)); %比较已确定的点与其相邻未确定点的距离
if((x(k).plus
x(k).min)&&((x(k).lastpoint=x(k).fb(i))||(x(k).newpoint=x(k).tb(j))))
%(意思就是判断路径长度和上面算到的最短路径相等,但是排除了我们上面的已经得到的路径,不然会一直循环下去。。。这里注释如果运行出错大家可以删掉,因为是我在写文章时加的,不在程序里,我怕这个百分号会出问题)
t=t+1;
x(t).tb=x(k).tb;
x(t).fb=x(k).fb;
x(t).pb=x(k).pb;
x(t).d=x(k).d;
x(t).path=x(k).path;
x(t).min=x(k).plus;
x(t).lastpoint=x(k).fb(i);
x(t).newpoint=x(k).tb(j);
x(t).d(x(t).newpoint)=x(t).min;
x(t).pb(x(t).newpoint)=1;
x(t).path(x(t).newpoint)=x(t).lastpoint; %最小值时的与之连接点
x(t).tb=find(x(t).pb==0);%找到还未找到最短路径的点
x(t).fb=find(x(t).pb);%找出已找到最短路径的点
end
end
end
x(k).d(x(k).newpoint)=x(k).min;
x(k).pb(x(k).newpoint)=1;
x(k).path(x(k).newpoint)=x(k).lastpoint; %最小值时的与之连接点
end
k=k+1;
end
end

PS:由于有时候会出现还未找到最短路径的点被划入已找到最短路径的点后,对再次循环并没有影响,那么我们程序里判断出了来的两条不同路径其实就是同一条路径(出结果后有重复路径,我花了好长时间才明白是这个原因)于是下面我又写了一个删除重复路径的简化函数

function [ x2 ] = simplify( x )
t=length(x);
for k=1:t
x1(k,:)=x(k).path
x2= unique(x1,‘rows’)
end

显示路径的函数依然没有变

function DisplayPath1dijkstrapro(route, start, dest)
% route 路径
% start :起点
% dest : 终点
%目标路径
t=1;
o=dest;%暂存上一点,且判断何时停止
y(1,t)=o;
while o~=start
o=route(o);
t=t+1;
y(1,t)=o;
end
n=length(y); %提取矩阵大小
for k=1:n
destpath(1,k)=y(1,n+1-k);
end
destpath
end

最后是主函数,在简化函数中我把结构体中的路径放在了数组里,因此主函数有稍稍改动
m= [0,4,inf,18,7,17, 11,inf;
4,0,2, inf,6,inf,15,inf;
inf,2,0, 9, 1, 8, inf,10;
18,inf,9,0,11,1, inf, 3;
7,6, 1, 11,0,10, 9, 4 ;
17,inf,8 ,1 10,0, inf, 2;
11,15,inf,inf,9,inf,0,5 ;
inf,inf,10, 3, 4, 2, 5, 0;];
start=1;dest=4;
[x,t]=dijkstrapro(m,start);
[ x2 ] = simplify( x );
[m,n]=size(x2)
for k=1:m
DisplayPath2dijkstrapro(x2(k,:), start, dest)
end
length=x(1).d(dest)

于是得到结果:
destpath = 1 5 8 6 4
destpath = 1 2 3 5 8 6 4
destpath = 1 5 8 4
destpath = 1 2 3 5 8 4
length = 14
我对照图上的ABCDEFGH 结果发现果然是这四条路,amazing!

接下来,我要去寻找flyod算法的多路径显示方法了,如果我直接在网上找到了,或者我自己也写不出来,那么你们可能就看不到我了。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
【old】mapX距离工具源码,delphi7+mapx5.0发布时间:2022-07-18
下一篇:
Matlab 取子矩阵发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap