A星算法1

A星算法

1.简述

A星算法就是试图在地图中找到一条[ 最短路径](https://so.csdn.net/so/search?q=%E6%9C%80%E7%9F%AD%E8%B7%AF%E5%BE%84&spm=1001.2101.3001.7020) ,但不保证一定存在。
  • 任务
    小猫去找青蛙玩(好TM弱智啊~)
  • 条件
    黑色方块无法通行,每走一个格子小猫消耗的体力都为1。

2.如果说你是小猫,你会怎么走?

嗯,毫无疑问 ![](https://img-blog.csdnimg.cn/img_convert/cc92f36416d76fd1d4a877f7464ad926.png) 你肯定这么走。。。很简单的对吧,但是你这么走的时候,真的没经过思考?并非如此吧,你要找最短路径是不是直接连线是最快的?但是连线有障碍物阻挡了,所以逼迫你先往上走出障碍物的区域,然后一路直线当然就是最短路径了。 BUT,你所做的思考,都是建立在你脑海里已经有整张地图的概念上,代码是不知道地图的,它要知道怎么走,就是一步一步的探索,你的行为对于代码来说,那叫-未卜先知!

3.基本概念

要实现A星算法,先要知道一些基本概念
  • open列表
    所谓open列表,我的理解是,知道但是没有走过的路
  • close列表
    已经走过的路
  • F值
    这个叫做和值,指的是走到终点消耗的代价值,这里就是指的是小猫消耗的体力了
    F = G + H,所以要知道F值,需要计算G和H的值
  • G值
    从起点到该点消耗的代价
  • H值
    从该点到终点的预估代价,为何G值不是预估,这里是预估呢?因为G值是从起点到该点,是一段已经走过的路程,代价是准确可知的,H值是到终点,但是这段路还没有走,所以是一段预估的值。

这些概念听起来有辣么一点对角懵逼~,没关系,我们实际演示下

4.手工走起

我们用粉色代表open列表,用绿色代表close列表 首先起点是我们走过的第一个点,将它先加入到close列表中![](https://img-blog.csdnimg.cn/img_convert/2f25534b2eee39357b19e3fbe8be83fe.png) 然后这只猫有四个方向可以选择,分别是上下左右,将这四个方块加入到open表中,表示知道但是还没走过的路,现在是决定怎么走的时候了,于是我们分别求着四个方块的F值。 G值都是很好求的,都是1,从起点走到这里嘛,都只走一步,H值从该点到终点的预估代价,这个可怎么求? 一般来说,这个值就是忽略所有障碍的情况下走出来的值,很明显,在这种只能直行的条件下,H值就是两点之间的横向格子数差加上纵向格子数差了 上格子 H = 横向7 + 纵向2 = 9 下格子 H = 横向7 + 纵向0 = 7 左格子 H = 横向8 + 纵向1 = 9 右格子 H = 横向6 + 纵向1 = 7 加上G值可以求得他们的F值分别为10,8,10,8 将这些数据标注在格子上 上面是F值,下左是G,下右是H ![](https://img-blog.csdnimg.cn/img_convert/23931ded152e963f7606e7553aa6b1a7.png) 有了这些数据,小猫就挑一个F值最小的走,这里8是最小,但是有两个,怎么办?无所谓了,随便走一条,但是一般是最后加入open表的那个格子。至于为什么无所谓,可以看完整篇文章反过来想想。 就走右边了,于是将右边的方块加入到close表,已经走过了嘛,记得要将它从open表中剔除 ![](https://img-blog.csdnimg.cn/img_convert/3a413ee94ffa2859b9a126c6f4f2fb8a.png)

接着在这个新的格子上,又有4个选择的方向,但是这里要注意了,每次选择新格子加入open列表的时候,要保证3点

  • 这个点不能在close表中
  • 这个点不能在open表中
  • 这个点是合法的,什么叫合法?这里简单的就是可以通行的,不能是障碍物

于是又加入了上下右三个点到open列表中,此时open列表已经有6个点了,接着计算这三个点的各项值

然后在open表中再次寻找F值最低的格子,发现是8,这里有3个,还是随意选一个,选下面的吧,将它从open表中剔除,加入close表中

紧接着再次寻找新的格子加入open列表中,依旧遵循上面说的3点,发现符合加入的只有右边的格子

接着还是计算新加入open列表的格子的值

在open列表中寻找F值最低的格子,发现还是8,有3个,我们选择最新加入的。

经过这几步之后,你是不是渐渐发现了规律?

5.伪代码

```plain 将起点加入close表 while(结束条件) { 获取close表的最后一个节点S 获取S点周围所有符合加入条件(条件就是指上文所说的那3点)的点,加入open列表 计算open列表F值最低的格子T T从open表中删除加入close表 } 再次循环的时候,是不是第一步获取的节点S就是最后加入的T了,如此就可以跟随着这个T,一步步的扩展路径了

结束条件:如果有这条路径存在,则是当青蛙所在的节点被加入到close后,寻路就结束了。
或者不存在这条路径,那么就是open列表中不再有节点的时候。
open列表实际上是一步步往外扩展的格子,当这个列表没有节点的时候并且终点还没有在close列表中,
那么说明所有能扩展到的格子已经都被走过了,仍然没有走到终点,此时便是没有这条路了

1
2
3
4
5
6
7
8
9
10
11
12
13
14


<h3 id="841d7cff"><font style="color:rgb(79, 79, 79);">6.注意项</font></h3>
<font style="color:rgb(77, 77, 77);">A星得到的结果是一条路径,这条路径最终是反推回去的,所以在写</font><font style="color:rgb(78, 161, 219);">Node</font><font style="color:rgb(77, 77, 77);">的数据结构时候,要记录这个节点是从哪个节点走过来的,也就是他的父节点,如此在最终才能反推回去。  
</font><font style="color:rgb(77, 77, 77);">A星不是沿着一条路走到黑的,你会发现它是不停地计算open表中最小F值的格子,当最小F值超过10的时候,你发现它又开始从F为10的格子上开始探索,实际上是几条不同的路径轮询的探索,最终走向终点,这也是为为何在open列表F值最低同时存在多个的时候,随便选择的原因,因为一旦探索的格子F值超过了这个最低值,它又会回到这个最低F值的格子上开始探索</font>

<h3 id="d140040a"><font style="color:rgb(79, 79, 79);">7.关于死胡同</font></h3>
<font style="color:rgb(77, 77, 77);">在我刚开始学习A星的时候,我总是会觉得,如果碰到死胡同,寻路仿佛就要终止,其实不然,A星是一个不同的搜索最小值过程的算法,除非open列表不存在,否则open列表中一定有一个是最小值的格子,只要存在这个格子,那么寻路就能继续下去,而对于最终的路径,我们是通过回溯的方式来获取,所以对于寻路,并不是说close表里的格子就都是路径了,想明白这回事,对A星就有比较明确的认识了</font>

[<font style="color:rgb(77, 77, 77);">转载自https://www.jianshu.com/p/65282bd32391</font>](https://www.jianshu.com/p/65282bd32391)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值