❶ dijkstra算法是什么
dijkstra算法最短路径算法。
Dijkstra是典型最短路径算法,用于计算一个节点到其他节点的最短路径。该算法使用的是贪心策略:每次都找出剩余顶点中与源点距离最近的一个顶点。
给定一带权图,图中每条边的权值是非负的,代表着两顶点之间的距离。指定图中的一顶点为源点,找出源点到其它顶点的最短路径和其长度的问题,即是单源最短路径问题。
Dijkstra的原理
(1)初始化时,S只含有源节点。
(2)从U中选取一个距离v最小的顶点k加入S中(该选定的距离就是v到k的最短路径长度)。
(3)以k为新考虑的中间点,修改U中各顶点的距离;若从源节点v到顶点u的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值是顶点k的距离加上k到u的距离。
❷ Dijkstra 算法是什么 Dijkstra 在哪里用
迪杰斯特拉算法用来解决从顶点v0出发到其余顶点的最短路径,该算法按照最短路径长度递增的顺序产生所以最短路径.
对于图G=(V,E),将图中的顶点分成两组:
第一组S:已求出的最短路径的终点集合(开始为{v0}).
第二组V-S:尚未求出最短路径的终点集合(开始为V-{v0}的全部结点).
算法将按最短路径长度的递增顺序逐个将第二组的顶点加入到第一组中,直到所有顶点都被加入到第一组顶点集S为止.
【算法思想】
g为用邻接矩阵表示的带权图.
(1)S
❸ 用dijkstra算法求a到f的最短路径
#include<stdio.h>
inta[205][205];//记录邻接矩阵
intdist[205];//到每个点的最短路
intm,n;//m条路,n个点
constintINF=0xfffffff;
voidinit()//初始化数据
{
for(inti=0;i<n;i++)
for(intj=0;j<n;j++)
a[i][j]=(i==j?0:INF);
}
voiddijkstra(intu)//从第u个点开始走
{
intsign[205]={0};//标记走过否
intx=u;
inti,j;
for(i=0;i<n;i++)//初始化到各点距离
dist[i]=a[x][i];
dist[x]=0;//到本身距离为0
sign[x]=1;//改点以走过
for(i=1;i<=n-2;i++)
{
intmin=INF;
for(j=0;j<n;j++)//在为走过的点中取距离x最短的点
{
if(!sign[j]&&min>dist[j])
{
min=dist[j];
x=j;
}
}
sign[x]=1;//标记,已走过
for(j=0;j<n;j++)//x以改变,更新dist[]值
{
if(!sign[j]&&dist[x]+a[x][j]<dist[j]&&a[x][j]<INF)
dist[j]=a[x][j]+dist[x];
}
}
}
intmain()
{
inti;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(i=0;i<m;i++)
{
intx,y,z;
scanf("%d%d%d",&x,&y,&z);
if(z<a[x][y])//取两点多条路最小路
a[x][y]=z;
if(z<a[y][x])
a[y][x]=z;
}
ints,t;
scanf("%d%d",&s,&t);
dijkstra(s);
if(dist[t]<2000000)
printf("%d ",dist[t]);
else
printf("-1 ");
}
return0;
}
参考链接 :http://blog.csdn.net/ouyangying123/article/details/38706957
❹ dijkstra算法是什么
迪杰斯特拉算法用于求解一个有向图(也可以是无向图,无向图是有向图的一种特例)的一个点(称之为原点)到其余各点(称之为周边点)的最短路径问题。算法构思很是巧妙(我这么认为),简直达到了“无心插柳柳成荫”的境界。算法本身并不是按照我们的思维习惯——求解从原点到第一个点的最短路径,再到第二个点的最短路径,直至最后求解完成到第n个点的最短路径,而是求解从原点出发的各有向路径的从小到大的排列(如果这个有向图中有环1-2-3-1算法岂不是永无终结之日了??!!),但是算法最终确实得到了从原点到图中其余各点的最短路径,可以说这是个副产品,对于算法的终结条件也应该以求得了原点到图中其余各点的最短路径为宜。清楚了算法的这种巧妙构思后,理解算法本身就不是难题了。
算法把一个图(G)中的点划分成了若干部分:
1):原点(v);
2):所有周边点(C);
另外有一个辅助集合S,从v到S中的点的最短路径已经求得。S的最初状态是空集。
这样就可以进一步划分图(G):
1):原点(v);
2):已求出v至其最短路径的周边点(S);
3):尚未求出v至其最短路径的周边点(Other=C-S);
算法的主体思想:
A、找到v——Other所有路径中的的最短路径vd=v——d(Other的一个元素);
B、找到v——S——Other所有路径中的的最短路径vi=v——i(Other的一个元素);
C、比较vd和vi如果vd<=vi则将d加入S且从Other中删除,否则将i加入S且从Other中删除。
重复以上步骤直至Other为空集。
我们求得的最短路径是升序排列的,那为什么下一条最短路径就存在于v——
❺ dijkstra算法有哪些
迪杰斯特拉算法用来解决从顶点v0出发到其余顶点的最短路径,该算法按照最短路径长度递增的顺序产生所以最短路径。
对于图G=(V,E),将图中的顶点分成两组:
第一组S:已求出的最短路径的终点集合(开始为{v0})。
第二组V-S:尚未求出最短路径的终点集合(开始为V-{v0}的全部结点)。
算法将按最短路径长度的递增顺序逐个将第二组的顶点加入到第一组中,直到所有顶点都被加入到第一组顶点集S为止。
(5)dijkstra算法csdn扩展阅读:
从dis数组选择最小值,则该值就是源点s到该值对应的顶点的最短路径,并且把该点加入到T中,此时完成一个顶点,需要看看新加入的顶点是否可以到达其他顶点并且看看通过该顶点到达其他点的路径长度是否比源点直接到达短,如果是,那么就替换这些顶点在dis中的值。 然后,又从dis中找出最小值,重复上述动作,直到T中包含了图的所有顶点。
❻ dijkstra算法是什么
Dijkstra算法是由荷兰计算机科学家狄克斯特拉(Dijkstra)于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。
其基本原理是:每次新扩展一个距离最短的点,更新与其相邻的点的距离。当所有边权都为正时,由于不会存在一个距离更短的没扩展过的点,所以这个点的距离永远不会再被改变,因而保证了算法的正确性。
不过根据这个原理,用Dijkstra求最短路的图不能有负权边,因为扩展到负权边的时候会产生更短的距离,有可能就破坏了已经更新的点距离不会改变的性质。
举例来说,如果图中的顶点表示城市,而边上的权重表示着城市间开车行经的距离。Dijkstra算法可以用来找到两个城市之间的最短路径。
Dijkstra算法的输入包含了一个有权重的有向图G,以及G中的一个来源顶点S。我们以V表示G中所有顶点的集合。每一个图中的边,都是两个顶点所形成的有序元素对。(u,v)表示从顶点u到v有路径相连。我们以E所有边的集合,而边的权重则由权重函数w: E→[0,∞]定义。
因此,w(u,v)就是从顶点u到顶点v的非负花费值(cost)。边的花费可以想象成两个顶点之间的距离。任两点间路径的花费值,就是该路径上所有边的花费值总和。
已知有V中有顶点s及t,Dijkstra算法可以找到s到t的最低花费路径(i.e.最短路径)。这个算法也可以在一个图中,找到从一个顶点s到任何其他顶点的最短路径。
❼ 图遍历算法之最短路径Dijkstra算法
最短路径问题是图论研究中一个经典算法问题,旨在寻找图中两节点或单个节点到其他节点之间的最短路径。根据问题的不同,算法的具体形式包括:
常用的最短路径算法包括:Dijkstra算法,A 算法,Bellman-Ford算法,SPFA算法(Bellman-Ford算法的改进版本),Floyd-Warshall算法,Johnson算法以及Bi-direction BFS算法。本文将重点介绍Dijkstra算法的原理以及实现。
Dijkstra算法,翻译作戴克斯特拉算法或迪杰斯特拉算法,于1956年由荷兰计算机科学家艾兹赫尔.戴克斯特拉提出,用于解决赋权有向图的 单源最短路径问题 。所谓单源最短路径问题是指确定起点,寻找该节点到图中任意节点的最短路径,算法可用于寻找两个城市中的最短路径或是解决着名的旅行商问题。
问题描述 :在无向图 中, 为图节点的集合, 为节点之间连线边的集合。假设每条边 的权重为 ,找到由顶点 到其余各个节点的最短路径(单源最短路径)。
为带权无向图,图中顶点 分为两组,第一组为已求出最短路径的顶点集合(用 表示)。初始时 只有源点,当求得一条最短路径时,便将新增顶点添加进 ,直到所有顶点加入 中,算法结束。第二组为未确定最短路径顶点集合(用 表示),随着 中顶点增加, 中顶点逐渐减少。
以下图为例,对Dijkstra算法的工作流程进行演示(以顶点 为起点):
注:
01) 是已计算出最短路径的顶点集合;
02) 是未计算出最短路径的顶点集合;
03) 表示顶点 到顶点 的最短距离为3
第1步 :选取顶点 添加进
第2步 :选取顶点 添加进 ,更新 中顶点最短距离
第3步 :选取顶点 添加进 ,更新 中顶点最短距离
第4步 :选取顶点 添加进 ,更新 中顶点最短距离
第5步 :选取顶点 添加进 ,更新 中顶点最短距离
第6步 :选取顶点 添加进 ,更新 中顶点最短距离
第7步 :选取顶点 添加进 ,更新 中顶点最短距离
示例:node编号1-7分别代表A,B,C,D,E,F,G
(s.paths <- shortest.paths(g, algorithm = "dijkstra"))输出结果:
(s.paths <- shortest.paths(g,4, algorithm = "dijkstra"))输出结果:
示例:
找到D(4)到G(7)的最短路径:
[1] 维基网络,最短路径问题: https://zh.wikipedia.org/wiki/%E6%9C%80%E7%9F%AD%E8%B7%AF%E9%97%AE%E9%A2%98 ;
[2]CSDN,Dijkstra算法原理: https://blog.csdn.net/yalishadaa/article/details/55827681 ;
[3]RDocumentation: https://www.rdocumentation.org/packages/RNeo4j/versions/1.6.4/topics/dijkstra ;
[4]RDocumentation: https://www.rdocumentation.org/packages/igraph/versions/0.1.1/topics/shortest.paths ;
[5]Pypi: https://pypi.org/project/Dijkstar/
❽ 最短路径 | 深入浅出Dijkstra算法(一)
上次我们介绍了神奇的只有 五行的 Floyd-Warshall 最短路算法 ,它可以方便的求得 任意两点的最短路径, 这称为 “多源最短路”。
这次来介绍 指定一个点(源点)到其余各个顶点的最短路径, 也叫做 “单源最短路径”。 例如求下图中的 1 号顶点到 2、3、4、5、6 号顶点的最短路径。
与 Floyd-Warshall 算法一样,这里仍然 使用二维数组 e 来存储顶点之间边的关系, 初始值如下。
我们还需要用 一个一维数组 dis 来存储 1 号顶点到其余各个顶点的初始路程, 我们可以称 dis 数组为 “距离表”, 如下。
我们将此时 dis 数组中的值称为 最短路的“估计值”。
既然是 求 1 号顶点到其余各个顶点的最短路程, 那就 先找一个离 1 号顶点最近的顶点。
通过数组 dis 可知当前离 1 号顶点最近是 2 号顶点。 当选择了 2 号顶点后,dis[2]的值就已经从“估计值”变为了“确定值”, 即 1 号顶点到 2 号顶点的最短路程就是当前 dis[2]值。
为什么呢?你想啊, 目前离 1 号顶点最近的是 2 号顶点,并且这个图所有的边都是正数,那么肯定不可能通过第三个顶点中转,使得 1 号顶点到 2 号顶点的路程进一步缩短了。 因此 1 号顶点到其它顶点的路程肯定没有 1 号到 2 号顶点短,对吧 O(∩_∩)O~
既然选了 2 号顶点,接下来再来看 2 号顶点 有哪些 出边 呢。有 2->3 和 2->4 这两条边。
先讨论 通过 2->3 这条边能否让 1 号顶点到 3 号顶点的路程变短。 也就是说现在来比较 dis[3] 和 dis[2]+e[2][3] 的大小。其中 dis[3]表示 1 号顶点到 3 号顶点的路程,dis[2]+e[2][3]中 dis[2]表示 1 号顶点到 2 号顶点的路程,e[2][3]表示 2->3 这条边。所以 dis[2]+e[2][3]就表示从 1 号顶点先到 2 号顶点,再通过 2->3 这条边,到达 3 号顶点的路程。
我们发现 dis[3]=12,dis[2]+e[2][3]=1+9=10,dis[3]>dis[2]+e[2][3],因此 dis[3]要更新为 10。这个过程有个专业术语叫做 “松弛” 。即 1 号顶点到 3 号顶点的路程即 dis[3],通过 2->3 这条边 松弛成功。 这便是 Dijkstra 算法的主要思想: 通过 “边” 来松弛 1 号顶点到其余各个顶点的路程。
同理通过 2->4(e[2][4]),可以将 dis[4]的值从 ∞ 松弛为 4(dis[4]初始为 ∞,dis[2]+e[2][4]=1+3=4,dis[4]>dis[2]+e[2][4],因此 dis[4]要更新为 4)。
刚才我们对 2 号顶点所有的出边进行了松弛。松弛完毕之后 dis 数组为:
接下来,继续在剩下的 3、4、5 和 6 号顶点中,选出离 1 号顶点最近的顶点。通过上面更新过 dis 数组,当前离 1 号顶点最近是 4 号顶点。此时,dis[4]的值已经从“估计值”变为了“确定值”。下面继续对 4 号顶点的所有出边(4->3,4->5 和 4->6)用刚才的方法进行松弛。松弛完毕之后 dis 数组为:
继续在剩下的 3、5 和 6 号顶点中,选出离 1 号顶点最近的顶点,这次选择 3 号顶点。此时,dis[3]的值已经从“估计值”变为了“确定值”。对 3 号顶点的所有出边(3->5)进行松弛。松弛完毕之后 dis 数组为:
继续在剩下的 5 和 6 号顶点中,选出离 1 号顶点最近的顶点,这次选择 5 号顶点。此时,dis[5]的值已经从“估计值”变为了“确定值”。对5号顶点的所有出边(5->4)进行松弛。松弛完毕之后 dis 数组为:
最后对 6 号顶点的所有出边进行松弛。因为这个例子中 6 号顶点没有出边,因此不用处理。 到此,dis 数组中所有的值都已经从“估计值”变为了“确定值”。
最终 dis 数组如下,这便是 1 号顶点到其余各个顶点的最短路径。
OK,现在来总结一下刚才的算法。 Dijkstra算法的基本思想是:每次找到离源点(上面例子的源点就是 1 号顶点)最近的一个顶点,然后以该顶点为中心进行扩展,最终得到源点到其余所有点的最短路径。
基本步骤如下:
在 博客 中看到两个比较有趣的问题,也是在学习Dijkstra时,可能会有疑问的问题。
当我们看到上面这个图的时候,凭借多年对平面几何的学习,会发现在“三角形ABC”中,满足不了 构成三角形的条件(任意两边之和大于第三边)。 纳尼,那为什么图中能那样子画?
还是“三角形ABC”,以A为起点,B为终点,如果按照平面几何的知识, “两点之间线段最短”, 那么,A到B的最短距离就应该是6(线段AB),但是,实际上A到B的最短距离却是3+2=5。这又怎么解释?
其实,之所以会有上面的疑问,是因为 对边的权值和边的长度这两个概念的混淆, 。之所以这样画,也只是为了方便理解(每个人写草稿的方式不同,你完全可以用别的方式表示,只要便于你理解即可)。
PS:数组实现邻接表可能较难理解,可以看一下 这里
参考资料:
Dijkstra算法是一种基于贪心策略的算法。每次新扩展一个路程最短的点,更新与其相邻的点的路程。当所有边权都为正时,由于不会存在一个路程更短的没扩展过的点,所以这个点的路程永远不会再被改变,因而保证了算法的正确性。
根据这个原理, 用Dijkstra算法求最短路径的图不能有负权边, 因为扩展到负权边的时候会产生更短的路径,有可能破坏了已经更新的点路径不会发生改变的性质。
那么,有没有可以求带负权边的指定顶点到其余各个顶点的最短路径算法(即“单源最短路径”问题)呢?答案是有的, Bellman-Ford算法 就是一种。(我们已经知道了 Floyd-Warshall 可以解决“多源最短路”问题,也要求图的边权均为正)
通过 邻接矩阵 的Dijkstra时间复杂度是 。其中每次找到离 1 号顶点最近的顶点的时间复杂度是 O(N),这里我们可以用 优先队列(堆) 来优化,使得这一部分的时间复杂度降低到 。这个我们将在后面讨论。
❾ 解释一下dijkstra算法这个计算过程的意思 怎么算的
最近也看到这个算法,不过主要是通过C语言介绍的,不太一样,但基本思想差不多。下面只是我个人的看法不一定准确。
Dijkstra算法主要解决指定某点(源点)到其他顶点的最短路径问题。
基本思想:每次找到离源点最近的顶点,然后以该顶点为中心(过渡顶点),最终找到源点到其余顶点的最短路。
t=1:令源点(v_0)的标号为永久标号(0,λ)(右上角加点), 其他为临时(+无穷,λ). 就是说v_0到v_0的距离是0,其他顶点到v_0的距离为+无穷。t=1时,例5.3上面的步骤(2)(3)并不能体现
t=2:第1步v_0(k=0)获得永久标号,记L_j为顶点标号当前的最短距离(比如v_0标号(0,λ)中L_0=0), 边(v_k,v_j)的权w_kj. 步骤(2)最关键,若v_0与v_j之间存在边,则比较L_k+w_kj与L_j, 而L_k+w_kj=L_0+w_0j<L_j=+无穷。
这里只有v_1,v_2与v_0存在边,所以当j=1,2时修改标号, 标号分别为(L_1, v_0)=(1, v_0), (L_2, v_0)=(4, v_0), 其他不变。步骤(3)比较所有临时标号中L_j最小的顶点, 这里L_1=1最小,v_1获得永久标号(右上角加点)。
t=3: 第2步中v_1获得永久标号(k=1), 同第2步一样,通过例5.3上面的步骤(2)(3),得到永久标号。 步骤(2),若v_1与v_j(j=2,3,4,5(除去获得永久标号的顶点))之间存在边,则比较L_1+w_1j与L_j。这里v_1与v_2,v_3,v_,4存在边,
对于v_2, L_1+w_12=1+2=3<L_2=4, 把v_2标号修改为(L_1+w_12, v_1)=(3, v_1);
对于v_3, L_1+w_13=1+7=8<L_3=+无穷, 把v_3标号修改为(L_1+w_13, v_1)=(8, v_1);
对于v_4, L_1+w_14=1+5=6<L_4=+无穷, 把v_4标号修改为(L_1+w_14, v_1)=(6, v_1);
v_5与v_1不存在边,标号不变。步骤(3), 找这些标号L_j最小的顶点,这里v_2标号最小
t=4: k=2, 与v_2存在边的未获得永久标号的顶点只有v_4, 比较L_2+w_24=3+1=4<L_4=6, 把v_4标号修改为(L_2+w_24, v_2)=(4, v_2); 其他不变。步骤(3), L_4=4最小。
t=5: k=4, 同理先找v_4邻接顶点,比较,修改标号,找L_j最小
t=6: 同理
啰嗦的这么多,其实步骤(2)是关键,就是通过比较更新最短路径,右上角标点的就是距离源点最近的顶点,之后每一步就添加一个新的”源点”,再找其他顶点与它的最短距离。
迪杰斯特拉算法(Dijkstra)(网络):
http://ke..com/link?url=gc_mamV4z7tpxwqju6BoqxVOZ_josbPNcGKtLYJ5GJsJT6U28koc_#4
里面有个动图,更形象地说明了该算法的过程。(其中每次标注的一个红色顶点out就和你的这本书中获得永久标号是相似的)
❿ dijkstra算法
[问题分析]
对于一个含有n个顶点和e条边的图来说,从某一个顶点Vi到其余任一顶点Vj的最短路径,可能是它们之间的边(Vi,Vj),也可能是经过k个中间顶点和k+1条边所形成的路径(1≤k≤n-2)。下面给出解决这个问题的Dijkstra算法思想。
设图G用邻接矩阵的方式存储在GA中,GA[i,j]=maxint表示Vi,Vj是不关联的,否则为权值(大于0的实数)。设集合S用来保存已求得最短路径的终点序号,初始时S=[Vi]表示只有源点,以后每求出一个终点Vj,就把它加入到集合中并作为新考虑的中间顶点。设数组dist[1..n]用来存储当前求得的最短路径,初始时Vi,Vj如果是关联的,则dist[j]等于权值,否则等于maxint,以后随着新考虑的中间顶点越来越多,dist[j]可能越来越小。再设一个与dist对应的数组path[1..n]用来存放当前最短路径的边,初始时为Vi到Vj的边,如果不存在边则为空。
执行时,先从S以外的顶点(即待求出最短路径的终点)所对应的dist数组元素中,找出其值最小的元素(假设为dist[m]),该元素值就是从源点Vi到终点Vm的最短路径长度,对应的path[m]中的顶点或边的序列即为最短路径。接着把Vm并入集合S中,然后以Vm作为新考虑的中间顶点,对S以外的每个顶点Vj,比较dist[m]+GA[m,j]的dist[j]的大小,若前者小,表明加入了新的中间顶点后可以得到更好的方案,即可求得更短的路径,则用它代替dist[j],同时把Vj或边(Vm,Vj)并入到path[j]中。重复以上过程n-2次,即可在dist数组中得到从源点到其余各终点的最段路径长度,对应的path数组中保存着相应的最段路径。
下面给出具体的Dijkstra算法框架(注:为了实现上的方便,用一个一维数组s[1..n]代替集合S,用来保存已求得最短路径的终点集合,即如果s[j]=0表示顶点Vj不在集合中,反之,s[j]=1表示顶点Vj已在集合中)。
Procere Dijkstra(GA,dist,path,i);
{表示求Vi到图G中其余顶点的最短路径,GA为图G的邻接矩阵,dist和path为变量型参数,
其中path的基类型为集合}
Begin
For j:=1 To n Do Begin {初始化}
If j<>i Then s[j]:=0 Else s[j]:=1;
dist[j]:=GA[i,j];
If dist[j]<maxint Then path[j]:=[i]+[j] Else path[j]:=[ ];
End;
For k:=1 To n-2 Do
Begin
w:=maxint;m:=i;
For j:=1 To n Do {求出第k个终点Vm}
If (s[j]=0) and (dist[j]<w) Then Begin m:=j;w:=dist[j]; End;
If m<>i Then s[m]:=1 else exit;
{若条件成立,则把Vm加入到S中,
否则退出循环,因为剩余的终点,其最短路径长度均为maxint,无需再计算下去}
For j:=1 To n Do {对s[j]=0的更优元素作必要修改}
If (s[j]=0) and (dist[m]+GA[m,j]<dist[j])
Then Begin Dist[j]:=dist[m]+GA[m,j];path[j]:=path[m]+[j];End;
End;
End;
(1)从一个顶点到其余各顶点的最短路径
对于一个含有n个顶点和e条边的图来说,从某个顶点vi到其余任一顶点vj的最短路径,可能是它们之间的边(vi,vj),也可能是经过k个中间点和k+1条边所形成的路径(1≤k ≤n-2)。
首先来分析Dijkstra的算法思想
设图G用邻接矩阵的方式存储在GA中,GA[I,j]=maxint表示vi,vj是不关联的,否则为权值(大于0的实数)。设集合S用来存储保存已求得最短路径的终点序号,初始时S=[vi]表示只有源点,以后每求出一个终点vj,就把它加入到集合中并作为新考虑的中间顶点。设数组dist[1..n]用来存储当前求得的最短路径,初始时vi,vj如果是关联的,则dist[j]等于权值,否则等于maxint,以后随着新考虑的中间顶点越来越多,dist[j]可能越来越小。再设一个与dist对应的数组path[1..n]用来存放当前最短路径的边,初始时vi到vj的边,如果不存在边则为空。
执行时,先从S以外的顶点(即待求出最短路径的终点)所对应的dist数组元素中,找出其值最小的元素(假设为dist[m]),该元素值就是从源点vi到终点vm的最短路径长度,对应的path[m]中的顶点或边的序列即为最短路径。接着把vm并入集合S中,然后以vm作为新考虑的中间顶点,对S以外的每个顶点vj,比较dist[m]+GA[i,j]与dist[j]的大小,若前者小,表明加入了新的中间顶点后可以得到更好的方案,即可求得更短的路径,则用它代替dist[j],同时把vj或边(vm,vj)并入到path[j]中。重复以上过程n-2次,即可在dist数组中得到从源点到其余个终点的最短路径长度,对应的path数组中保存着相应的最短路径。
为了实现上的方便,用一个一维数组s[1..n]代替集合s,用来保存已求得最短路径的终点集合,即如果s[j]=0表示顶点vj不在集合中,反之,s[j]表示顶点vj已在集合中)。
Procere dijkstra (GA,dist path,I)
begin
for j:= 1 to n do begin
if j<>I then s[j]:=0;{j不在集合中} else s[j]:=1;{j在集合中};
dist[j]:=GA[I,J];
IF dist [j]<maxint {maxint为假设的一个足够大的数}
Then path [j]:=[I]+[j]
Else path[j]:=[ ];
End;
For k:= 1 to n-1 do begin w:=maxint;m:=I;
For j:= 1 to n do{求出第k个终点Vm}
if (s[j]=0)and(dist[j]<w) then begin m:=j;w:=dist[j];end;
If m<>I then s[m]:=1 else exit;{若条件成立,则把Vm加入到s中,否则退出循环,因为
剩余的终点,其最短路径长度均为maxint,无需再计算下去}
for j:=1 to n do {对s[j]=0的更优元素作必要修改}
if (s[j]=0)and (dist[m]+GA[m,j]<dist[j])
then begin
dist[j]:=dist[m]+GA[m,j];
path[j]:=path[m]+[j];
End;
End;
End;
用集合的思想:
for k:=1 to n-1 do
begin
wm:=max;j:=0;
for i:=1 to n do
if not(i in s)and(dist[i]<wm) then begin j:=i;wm:=dist[i];end;
s:=s+[j];
for i:=1 to n do
if not(i in s)and(dist[j]+cost[j,i]<dist[i]) then
begin dist[i]:=dist[j]+cost[j,i];path[i]:=path[j]+char(48+i);end;
end;