[我的第一本算法书] 第四章 摘录 图 广度优先搜索 深度优先搜索 贝尔曼-福特算法 Dijkstra算法 A*算法

广度优先搜索算法

广度优先搜索算法:是一种对图进行搜索的算法.假设我们一开始位于某个顶点(即起点),此时并不知道图的整体结构,而我们的目的是从起点开始顺着边搜索,直到到达指定顶点(即终点).在此过程中每走到一个顶点,就会判断一次它是否为终点.广度优先搜索会优先从离起点近的顶点开始搜索.
在这里插入图片描述在这里插入图片描述在这里插入图片描述
广度优先搜索的特征为从起点开始,由近及远进行广泛的搜索.因此,目标顶点离起点越近,搜索结束得越快.
在这里插入图片描述

深度优先搜索

深度优先搜索和广度优先搜索一样,都是对图进行搜索的算法,目的都是从起点开始搜索直到达到指定顶点(终点).深度优先搜索会沿着一条路径不断往下搜索直到不能再继续为止,然后再折返,开始搜索下一条候补路径.在这里插入图片描述在这里插入图片描述
要特别注意的是:此处,候补顶点用’后入先出’(LIFO)的方式来管理的,因此可以使用’栈’这个数据结构在这里插入图片描述

深度优先搜索的特征为沿着一条路径不断往下,进行深度搜索.虽然广度优先搜索和深度优先搜索在搜索顺序上有着很大的差异,但是在操作步骤上却只有一点不同,那就是选择哪一个候补顶点作为下一个顶点的基准不同.
广度优先搜索选择的是最早成为候补的顶点,因为顶点离起点越近就越早成为候补,所以会从离起点近的地方开始按顺序搜索;而深度优先搜索选择的则是最新成为候补的顶点,所以会一路往下,沿着新发现的路径不断深入搜索.

贝尔曼-福特算法

贝尔曼-福特算法是一种在图中求解最短路径问题的算法.最短路径问题就是在加权图指定了起点和终点的前提下,寻找从起点到终点的路径中权重总和最小的那条路径.在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
将图的顶点设为n,边数设为m,我们来思考一下贝尔曼-福特算法的时间复杂度是多少.该算法经过n轮更新操作后就会停止,而在每轮更新操作中都需要对各个边进行1次确认,因此1轮更新所花费的时间就是O(m),整体的时间复杂度就是O(mn).
为了便于说明,前面的讲解以无向图为例,但在有向图中同样可以求解最短路径问题,选出一条边并计算顶点的权重时,在有向图中只按照边所指向的那个方向来计算就可以了.
补充说明:计算最短路径时,边的权重代表的通常是时间,距离或者路费等,因此基本都是非负数,不过,即便权重为负,贝尔曼-福特算法也可以正常运行.
但是,如果在一个闭环中边的权重总和是负数,那么只要不断遍历这个闭环,路径的权重就能不断减小,也就是说根本不存在最短路径,遇到这种对顶点进行n次更新操作后仍能继续更新的情况,就可以认定它’不存在最短路径’
贝尔曼-福特算法的名称取自其创始人理查德-贝尔曼和莱斯特-福特的名字.贝尔曼也因为提出了该算法的一个重要分支’动态规划’而被世人所熟知.

狄克斯特拉算法

与前面提到的贝尔曼-福特算法类似,狄克斯特拉算法也是求解最短路径问题的算法.使用它可以求得从起点到终点的路径中权重总和最小的那条路径.在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
比起需要对所有的边都要重复计算权重并更新权重的贝尔曼-福特算法.狄克斯特拉算法多了一步选择顶点的操作,这使得它在求最短路径上更为高效.
将图的顶点数设为n,边数设为m,那么如果实现不进行任何处理,该算法的时间复杂度就是O(n^2).不过,如果对数据结构进行优化,那么时间复杂度就会变为O(m+nlogn)在这里插入图片描述
对于有负数权重的边的图,狄克斯特拉算法可能会算出错误的路径,实际上是没有最短路径的,而贝尔曼-福特算法是可以发现没有最短路径的.
所以,对于权重有负数的情况,可以使用贝尔曼-福特算法,不然的话使用狄克斯特拉算法更加高效.

A*算法

A star算法也是一种在图中求解最短路径问题的算法,由狄克斯特拉算法发展而来.狄克斯特拉算法会从离起点近的顶点开始,按顺序求出起点到各个顶点的最短路径,也就是说,一些距离远的顶点的最短路径会先被算出来,但这部分其实是无用的.与之不同,A就会预先估算一个值,并利用这个值来省去一些无用的计算.在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
如果我们能够得到一些启发信息,即各个顶点到终点的大致距离(这个距离不需要是准确的值),我们就能使用A
算法.当然,有时这类信息完全无法估算,这是就不能使用A算法.
A
算法在游戏编程中经常被用于计算敌人追赶玩家时的行动路线等,但由于该算法的计算量较大,所以可能会使游戏整体的运行速度变慢.因此在实际编程中,需要考虑结合其他算法,或者根据具体的应用场景做出相应调整.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值