最短路问题的总结与反思

最短路问题的总结与反思

前言

  • 什么是最短路问题?

每当我们使用BD(还有GD和TX)地图的时候,每当我们输入我们的目的地,软件会自动给我们分配路径,而这些路径包括这到达所需要的时间和所需要的路程,这个就是最短路问题。

我们给定一个定义:给定一个有向图G=(V,E),\left | V\right |=n\left | E \right |=m,节点以[1,n]之间的连续整数编号,(x,y,z)描述一条从x出发,到达y,长度为z的有向边。

  • 最短路问题所需要什么算法思想?

对于最短路问题,我们有三种算法来计算最短路。1.Floyd算法2.Dijkstra(迪杰斯特拉)算法3.Bellman-ford(SPFA)算法

  1. Floyd算法:

思路:

该方法的本质是动态规划的思想。

状态转移方程:dis[k,i,j]=min(dis[k,i,j],dis[k-1,i,k]+dis[k-1,k,j]);

解析:

此状态转移方程是表示点i经过点k-1到j最小还是点i到点j原来的路径最小。  

  1. Dijkstra(迪杰斯特拉)算法:

思路:

①定义一个dis数组,初始化所有除起点的点全部为极大值(INF),并把起点dis[s]=0//表示当前所有的点都还不可达,并且起点到起点的路径(也是最短路)为0。

定义一个布尔型的vis数组,表示当前是否是已经找到最短路了。

②在dis数组里找出一个最小值,表示当前的点已经为最短路径,并标记vis[x]=1。

扫描节点x所连接的边,若dis[x]+z<dis[y],则dis[y]=dis[x]+z。//更新操作。

③重复步骤②,一直到所有的点全部标记为止,此时dis[x]表示s到其他n-1点的最短路径。

//Dijkstra算法是基于贪心的思想,仅适用于所有非负的边。当边长z都是非负的时候,全局最小值不可能再被其他节点更新(因为都是最小值了),故在②中所选择的dis数组中最小的一定是当前起点到该点的最短路。

Dijkstra(迪杰斯特拉)算法堆优化:

上面的算法时间复杂度为O(n^{2}),此时能够优化的地方在于寻找dis数组里的最小值,故可以将程序转变为O(nlogn)。

思路:

将上述步骤②“在dis数组里找出一个最小值”中,我们可以定义一个优先队列,以dis值为关键字,从小到大排序,即可以降低时间复杂度。从O(n^{2})下降到O(nlogn)。

  1. Bellman-ford算法(SPFA):
  2. 原理:

它的原理是基于对图进行|V-1|进行松弛操作,得到所有可能的最短路径其优于迪科斯彻算法的方面是边的权值可以为负数、实现简单,缺点是时间复杂度过高,高达O(nm)。

每次松弛操作实际上是对相邻节点的访问,第n次松弛操作保证了所有深度为n的最短路

思路:

①定义一个dis数组,初始化所有除起点的点全部为极大值(INF),dis[s]=0(起点到自己的最短路就是0),然后遍历所有的点对应的边(这里我们用SPFA优化)。

②定义一个队列(queue),将起点放入队列中。

③只要队列里面有数(只要队列不为空)就取队头进行遍历所邻接的点。当所邻接的点被更新(松弛)的时候,将此点入队列。一直到结束(队列为空的时候)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值