dijkstra伪代码翻译java_Dijkstra算法

本文详细介绍了Dijkstra算法,用于解决单源最短路径问题。算法通过设置已访问顶点集合,每次选择未访问顶点中与起点距离最小的一个进行访问,并更新其相邻顶点的最短距离。文章提供了伪代码和Java实现,包括邻接矩阵和邻接表两种版本,并讨论了如何使用Dijkstra算法求解最短路径及其优化。
摘要由CSDN通过智能技术生成

最短路径是图论中一个很经典的问题:给定图G(V,E),求一条从起点到终点的路径,使得这条路径上经过的所有边的边权之和最小。

对任意给出的图G(V,E)和起点S、终点T,如何求从S到T的最短路径。解决最短路径问题的常用算法有Dijkstra算法、Bellman-Ford算法、SPEA算法和Floyd算法。

1.Dijkstra算法

Dijkstra算法(读者可以将其读作“迪杰斯特拉算法”)用来解决单源最短路问题,即给定图G和起点s,通过算法得到S到达其他每个顶点的最短距离。Dijkstra的基本思想是对图G(V,B)设置集合S,存放已被访问的顶点,然后每次从集合V-S中选择与起点s的最短距离最小的一个顶点(记为u),访问并加入集合S。之后,令顶点u为中介点,优化起点s与所有从u能到达的顶点v之间的最短距离。这样的操作执行n次(n为顶点个数),直到集合S已包含所有顶点。

单源最短路径:从起点V出发,每个顶点之间的路程尽可能短,即从起点到达其他所有顶点都必须是最短距离。

①将地图上所有边都抹去,只有当到达这个顶点后才把从这个顶点出去的边显现(笔者插话:这个操作在实际编写代码时是自然成立、不需要人为控制的,但是在这单独提出来对理解Dijkstra操作的过程很有帮助)。

②在地图中的顶点V(0≤i≤5)上记录从起点V0到达该城市所需要的最短距离。由于在①中所有边都被抹去了,因此在初始状态下除了V0到达V0的距离是0之外,从V到达其他顶点的距离都是无穷大(记为INF)。为了方便叙述,在下文中某几处出现的最短距离都是指从起点V0到达顶点V的最短距离。

下面是行动策略:

①由于要攻占六个顶点,因此将步骤②③执行六次,每次攻占一个顶点(如果是n个顶点,那么就执行n次)。

②每次都从还未攻占的城市中选择当前距离起点V0最近的城市(即地图的顶点上记录的最短距离最小的未到达的顶点,记为Vk(0≤k≤5)。

③到达顶点Vk后,开放地图上从Vk出发的所有边,并査看以Vk为中介点的情况下,能否使从起点V0到达某些还未到达的顶点的最短距离变小。如果能,则将那个最短距离覆盖到对应的城市上(因为开放了从Vk出发的边,因此有了改善某些顶点最短距离的可能,且当前只有Vk能够优化这个最短距离)。

首先,Dijkstra算法解决的是单源最短路问题,即给定图G(V,E)和起点s(起点又称为源点),求从起点s到达其它顶点的最短距离。Dijkstra算法的策略是:设置集合S存放已被访问的顶点(即已到达的顶点),然后执行n次下面的两个步骤(n为顶点个数)。

①每次从集合V-S(即未到达的顶点)中选择与起点s的最短距离最小的一个顶点(记为u),访问并加入集合S(即令其已被访问)。

②之后,令顶点u为中介点,优化起点s与所有从u能到达的顶点v之间的最短距离。

Dijkstra算法的具体实现:由于Dijkstra算法的策略比较偏重于理论化,因此为了方便编写代码,需要想办法来实现策略中两个较为关键的东西,即集合S的实现、起点s到达顶点Vi(0≤i≤n-1)的最短距离的实现。

①集合S可以用一个bool型数组vis[]来实现,即当vis[i]=true时表示顶点Vi已被访问,当vis[i]=false时表示顶点Vi未被访问。

②令int型数组表示起点s到达顶点V的最短距离,初始时除了起点s的的d[s]赋为0,其余顶点都赋为一个很大的数(10^9)来表示INF,即不可达。

接下来看看实现Dijkstra算法的伪代码。其实很短,不难,希望读者能够结合上面好好理解一下这个伪代码,然后再往下看:

//G为图,一般设成全局变量;数组d为源点到达各点的最短路径长度,s为起点

Dijkstra(G,d[],s){

初始化

for(循环n次){

u = 使d[u]最小的还未访问的顶点的标号;

记u已被访问;

for(从u出发能到达的所有顶点v){

if(v未被访问&&以u为中介点使s到顶点v的最短距离d[v]更优){

优化d[v];

}

}

}

}

由于图可以使用邻接矩阵或者邻接表来实现,因此也就会有两种写法,但是这两种写法都是以上面的伪代码为基础的,区别主要集中在枚举从u出发能到达的顶点v上面:邻接矩阵需要枚举所有顶点来查看v是否可由u到达;邻接表则可以直接得到u能到达的顶点v。在写出具体函数之前,需要先定

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值