Dijkstra算法是寻找最短路径的一种搜索算法,由荷兰科学家提出。
1)算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径, 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。
在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v 到U中任何顶点的最短路径长度。
此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。
2)算法步骤:
a.初始时,S只包含源点,即S={v},v的距离为0。
U包含除v外的其他顶点,
即:U={其余顶点},若v与U中顶点u有边,则<u,v>正常有权值,若u不是v的出边邻接点,则<u,v>权值为∞。
b.从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k
的最短路径长度)。
c.以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u的距离(经
过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。
d.重复步骤b和c直到所有顶点都包含在S中。
算法描述:通过为每个节点保留目前为止所找到的从s到e的最短路径。
为了记录最佳路径轨迹,记录路径上每个节点的前趋,通过回溯法找出最短路径轨迹。
过程如下:
在网上搜索一些版本的Matlab实现方法,感觉都有些毛病。
经过修改,得到比较好的效果。
[cpp]view plain copy
1.function [ distance path] = Dijk( W,st,e )
2.%DIJK Summary of this function goes here
3.% W 权值矩阵 st 搜索的起点 e 搜索的终点
4.n=length(W);%节点数
5. D = W(st,:);
6.visit= ones(1:n); visit(st)=0;
7.parent = zeros(1,n);%记录每个节点的上一个节点
8.
9.path =[];
10.
11.for i=1:n-1
12. temp = [];
13. %从起点出发,找最短距离的下一个点,每次不会重复原来的轨迹,设置visit判断节点是
否访问
14.for j=1:n
15.if visit(j)
16. temp =[temp D(j)];
17.else
18. temp =[temp inf];
19. end
20.
21. end
22.
23. [value,index] = min(temp);
24.
25. visit(index) = 0;
26.
27. %更新如果经过index节点,从起点到每个节点的路径长度更小,则更新,记录前趋节点,
方便后面回溯循迹
28.for k=1:n
29.if D(k)>D(index)+W(index,k)
30. D(k) = D(index)+W(index,k);
31. parent(k) = index;
32. end
33. end
34.
35.
36.end
37.
38.distance = D(e);%最短距离
39.%回溯法从尾部往前寻找搜索路径
40.t = e;
41.while t~=st && t>0
42. path =[t,path];
43. p=parent(t);t=p;
44.end
45.path =[st,path];%最短路径
46.
47.
48.end
测试:
测试用例1
[cpp]view plain copy
1.W=[0 50 inf 40 25 10
2. 50 0 15 20 inf 25
3. inf 15 0 10 20 inf
4. 40 20 10 0 10 25
5. 25 inf 20 10 0 55
6. 10 25 inf 25 55 0];
[cpp]view plain copy
1.
[cpp]view plain copy
1.[distance,path]=Dijk(W,1,4);
>> distance
distance =
35
>> path
path =
1 6 4
从节点1到节点4最短距离路径为1-->6-->4, 最短距离为35
测试用例2
[html]view plain copy
1.W=[0 1 3 4
2. 1 0 2 inf
3. 3 2 0 5
4. 4 inf 5 0];
[html]view plain copy
1.[distance,path]=Dijk(W,2,4);
>> distance
distance =
5
>> path
path =
2 1 4
从节点2到节点4最短距离路径为2-->1-->4, 最短距离为5。