关于A 星算法的研究与简单分析及其实现

Hanzack@163.com

(本文为自己所写例子为本人所创,欢迎批评指责,大家一起讨论,若转载请注明作者)

A星算法:从起始点开始,找它的所有子节点,加入到一个特殊队列priorityQueue(简称pQ)中(类似于一个数组)。 然后利用一个特殊函数对这些点进行打分, 这个特殊函数我们简单称为启发函数。   根据打分选出最好的点。 把这个节点从pQ队列中删除,并把这个节点的的所有子节点加入到pQ队列中。 循环这个步骤 知道找到到达终点的最短路径。

几个简单小问题:

1.     当一个节点没有子节点的时候怎么办?

不可能没有, B连接D, 那么互为子节点。

2.     当一个节点的子节点为目的点时候,怎么找到到达该目的点过程中的所有节点?

每一个节点都要封装为一个对象,存储着自己的父节点。由于每一个节点都可能有几个父节点,此时我们只要存储:在最短路径上该点的上一个节点为父节点即可。

(根据打分来看,该点是从哪一点过来的,那么就存储那一点为父节点)

二:

A星算法的简单图文描述:

先把A点加入队列pQ, 然后找到A点的子节点B, C, D 数字表示分数(这里数字越小表示越好)。然后把队列中的A点删除放入到一个封闭队列  close中(理解为一个叫做close的数组变量或者集合变量)。

然后从队列pQ,中找到分数最好的点, 这时候明显选B点,然后把E,F点加入到pQ队列中。并且把B移动到封闭队列中。 此时pQ中有如下几个点:  C, D, E, F。 显然分数最好的是C点, 然后。。。。。。重复上述行为,直到找到终点。

简单来说,找到一个点,把它的子节点加入队列,再从队列中所有点中找到分数最好的点,循环。

三:理解大致理论后的难点。

而在做代码实现时,涉及的难点为:

1.     每次找一个点的子节点的时候不能直接把子节点直接全部加入到队列中:

a.     由于无向图中相连节点互为子节点, 所以先判断该子节点是否已经在close队列中了(就是要先判断是否已经被访问过了)。

b.     还要判断该子节点是否已经在pQ队列中,因为它也有可能是别人的子节点,而已经被加入到了pQ中。

c.     那么如果都不是,就可以加入到pQ队列中了。

d.     否则,是不是不用考虑它直接看下一个子节点呢? 不是,而是要做条件判断做其他考虑。

2.     关于pQ队列, 写一个pQ的类用来按照分数的好坏来排序pQ队列中的对象(这里存储的是节点)。这个类的写法可以参考stack的原理。  把stack的先进后出FILO 原理改为,进来了按照分数决定先出后出。

3.     书写一个节点类,每一个节点都是一个打包好的对象,有属性:父节点, 权值()

四:  最需要看的案例-----详细告诉你以下原因

1.     为什么在把子节点加入到队列中前需要检查该节点是否已经在于队列中?

2.     为什么为什么在把子节点加入到队列中前需要检查该节点是否已经在于封闭列表里,如果在封闭列表里,为什么又会产生把它从封闭列表里面拉出来的情形。

逻辑如下:

此处使用的函数为  F=g + h,每一个点的分值函数都是F. 其中 g:从起点开始经由过路点到该点的距离, h是一个估值函数,此处使用的估值函数为欧几里得距离,即从该点到目的点X的直线距离(为什么使用这个函数,因为这个距离是两点可能的最小距离。请自行查看启发函数的目的和用处)

1.      A.由图和分值函数F可以看出,第一点为A点, 它的F值=g+h=0(从起始点A到A点的距离为0)+ A到X的距离。

Fa=1000

B.  Fb=AB距离+BX距离   为600

C. Fc=AC+CX       为670

2. 当由A点开始,先把A点的子节点找出来暂时先不放到队列中,并把A点放入到封闭队列close中去。现在开始检查子节点是否可以并且怎样的方式进入队列

a.  先判断子节点是否在close队列中。发现所有子节点(B,C)不在

b.  判断子节点是否已经出现在了pQ队列中。 不在

此时将两个节点加入到pQ队列中

3 .  从队列中找出一个分数最高的, 由于队列中只有两个点:B, (f=100+500) 和C (f=70+600)

故将B点找出来(600《670 距离越小越好), 并且去找它的子节点。

此时B的子节点一共有A, C, D  三点

a.      先判断子节点是否在close队列中。

发现A在封闭列表里:

此时要判断A点新的F值是否比原来的F值(1000)小?

是---》将A点的F值该为新的并且把它移动进pQ中

否---》去看下一个子节点,不在考虑A点。

那么这时候A点新的F值是多少呢?

F新= 从A点经由B点到A点的距离+AX距离=100+100+1000

发现C 不在close队列中,

发现D不在close队列中

   发现E不在close队列中

b.      判断子节点是否已经出现在了pQ队列中。

此处不考虑A点,因为上一步已经发现它在close队列中,且不满足被拉出来的条件

发现D不在pQ队列中

发现E不在pQ队列中

故把D, E 加入到pQ队列中。注意此时:Fd=(AB+BD)+DX=750

Fe=(AB+BE)+EX=1100

发现C在pQ队列中,原来的F值为670

经由B点过来的F值为:100+10+600=710.

710》670  所以C的F值不用改变,C的父节点仍然是A

所以经过以上步奏:(两个列表有以下值:)

Close:  A(仍然保留),   B(新加入的)

PQ:    C(无需更改), D,E

4 . 已经找了两个点了, 现在继续从pQ剩余点中找出距离最小的点。发现是C点,F

值只有670。

a.      先判断子节点是否在close队列中。

发现A在封闭列表里:

此时要判断A点新的F值是否比原来的F值(1000)小?

是---》将A点的F值该为新的并且把它移动进pQ中

还要修改父节点

否---》去看下一个子节点,不在考虑A点。

那么这时候A点新的F值是多少呢?

F新= 从A点经由C点到A点的距离+ AX距离=70+70+1000=1140

发现B在close队列中,

此时要判断B点新的F值是否比原来的F值(600)小?

是---》将B点的F值改为新的并且把它移动进pQ中

还要把B点的父节点变为C, 原来的是A

否---》去看下一个子节点,不在考虑B点。

那么这时候B点新的F值是多少呢?

F新= 从A点经由C点到B点的距离+ AX距离=70+10+500=580

发现比原来F值小。

   发现E不在close队列中

 

b . 判断子节点是否已经出现在了pQ队列中。

此处不考虑B点,因为上一步已经发现它在close队列中,且满足被拉出来的条件

发现E已经在pQ队列中

E原来是由B节点产生的子节点所以它原来的F=100+700+300=1100

现在经由C点产生的F值= 70+400+300=770

此时修改  E的F值从1100改为770, 并且把父节点从B改为C

所以经过以上步奏:(两个列表有以下值:)

Close:  A(仍然保留F=1000),   B(移动进pQ)  C, (新加入的F=670)

PQ:    C(移除), D (F=750),E(F值被修改成了770)  B(又移动回来了F=580)

5 .  继续从剩下的点中找F值最小点。 显然又是找到B,

a.      先判断子节点是否在close队列中。

发现A在封闭列表里:

此时要判断A点新的F值是否比原来的F值(1000)小?

是---》将A点的F值该为新的并且把它移动进pQ中

还要修改父节点

否---》去看下一个子节点,不在考虑A点。

那么这时候A点新的F值是多少呢?

F新= 从A点经由C点到B点再到A点的距离+ AX距离=1180

发现C在close队列中,

此时要判断C点新的F值是否比原来的F值(670)小?

是---》将B点的F值改为新的并且把它移动进pQ中

还要把B点的父节点变为C原来的是A

否---》去看下一个子节点,不在考虑B点。

那么这时候C点新的F值是多少呢?

F新= 从A点经由C点到B点再回到C点+ CX距离=690

发现比原来F值大。

   发现E不在close队列中

   发现D不在close队列中

b . 判断子节点是否已经出现在了pQ队列中。

此处不再考虑A点,C点

E已经被上一步C作为父节点所修改了

现在经由B点产生的新F值= 70+10+700+300=1080

D   原来F值为750   现在经由ACBD路线是730,父节点从B变为B

所以经过以上步奏:(两个列表有以下值:)

Close:  A(仍然保留F=1000),   B(重新移回)  C, (仍然保留)

PQ:    D (F修改为730),E(F值被修改成了770)  B(被移动出去了F为570)

6.  这时候分数最好的点是D, 找子节点,只有两个一个是X一个是B。

分析方法同上。

区别是, x的分值函数F=g+h,   h=0

g= AC+CB+BD+DX=70+10+300+350=730,故X的F值若经由D则是730.

把X点加入到pQ队列中去

所以经过以上步奏:(两个列表有以下值:)

Close:  A(仍然保留F=1000),   B(保留)  C, (仍然保留)  D(新加进来的)

PQ:    D (F修改为730),E(F值被修改成了770)  B(被移动出去了F为570)

X(新加进来的)

7.  此时,发现X 和E比选   X

当找X子节点之前(while的条件)发现, X是终点就结束循环。

如果,E比X小, 我们就重新分解E。。。

8.  根据X点依次找父节点就可以找到路径。

此处为  ACBDX

至此全部完成。(将2,3,4,5,6,7  步融合成一个while循环)

While的条件为  currNode 是否为X目标点         currNode就是那个要被分解的点(例如一开始的A点)。

问题:

1.      如果AX的直线距离只有100, 那么A的F值就是0+100=100.   那不是每次都找自己?

当然不是, 如果F值是100, 第一次找它,分解子节点以后(X不是子节点),就把它扔到了closed列表中去了。 下次找最小值的时候是从pQ队列中找的。由于没有X,所以还是会继续找到C,

以下是代码逻辑:

While(! CurrNode is targetNode):

{

For  currNode  的所有子节点

If  该子节点在close 列表中

{  If   该子节点的刚算出来的F值小于原来的F值

{  把该子节点的父节点更新

把该子节点移动到pQ中}}

Else if  该子节点已经在pQ中

{   If   该子节点的刚算出来的F值小于原来的F值

把该子节点的父节点更新 }

Else:

{ 把该子节点加入到pQ中去 }

If pQ ==null :  return null.     //说明没有点到达

令currNode等于pQ列表中的F最小值

将该点移出pQ

}

关于A 星算法的研究与简单分析及其实现-A star相关推荐

  1. 基于matlab的数字图像边缘检测算法研究,基于MATLAB数字图像边缘检测算法的研究与对比分析...

    ·161· 居 舍 研究探讨 2017年10月(中) 1 绪论 图像边缘中通常包含着重要的边界信息,这些边界信息便于分析和研究图像.另外,边缘检测可以大大降低图像处 理的工作量,将提高图像分析的效率. ...

  2. 不到一百行python代码简单实现A星算法

    为了更好地理解A星算法,自己手撸了一段91行的代码来实现A星算法 可能代码风格不是很好,因为这也就是一上午写出来的,只是简单实现了A星 过两天准备好好改动一下代码使其更易读,再好好备注一下. #pyt ...

  3. cocos2d-x游戏实例(6)-A星算法(2)

    小满(bill man)个人原创,欢迎转载,转载请注明地址,小满(bill man)的专栏地址http://blog.csdn.net/bill_man 上一篇中我们研究了A星算法的基本概念,本篇介绍 ...

  4. 地图信息,障碍判断以及寻路算法(A星算法,B星算法和蚁群算法等)

    一.广度优先遍历和深度优先遍历 在学习寻路算法之前,我们先来了解一下广度优先遍历和深度优先遍历. 什么是广度优先遍历? 广度优先遍历(breadth first search)是一个万能的算法. 广度 ...

  5. 分布式数据库系统查询优化算法的研究

    分布式数据库系统查询优化算法的研究 摘  要:自分布式数据库诞生以来,人们对于分布式数据库查询优化的研究就一直处于进行时.由于分布式数据库物理上分布而逻辑上集中等特性,其查询优化问题较集中式数据库来说 ...

  6. 全基因组关联分析中上位性检测算法的研究

    全基因组关联分析中上位性检测算法的研究 前言 这个项目主要是分享一些全基因组关联分析中上位性检测算法的研究经验,算是,怎么入门,写这么个东西,一是做总结,二是咱实验室估计以后还会有做这个方向的,备着吧 ...

  7. cocos2d-x游戏实例(5)-A星算法(1)

    小满(bill man)个人原创,欢迎转载,转载请注明地址,小满(bill man)的专栏地址http://blog.csdn.net/bill_man 继续上一篇地图上的处理,不过和本篇相比,我们之 ...

  8. cocos2d-x游戏实例(8)-A星算法(4)

    小满(bill man)个人原创,欢迎转载,转载请注明地址,小满(bill man)的专栏地址http://blog.csdn.net/bill_man 继续A星算法,我们在经历了地图的检测,并且检测 ...

  9. cocos2d-x游戏实例(7)-A星算法(3)

    小满(bill man)个人原创,欢迎转载,转载请注明地址,小满(bill man)的专栏地址http://blog.csdn.net/bill_man 继续上一篇的内容,我们再看我们上一篇进行的部分 ...

  10. R-Tree空间索引算法的研究历程和最新进展分析

    摘要:本文介绍了空间索引的概念.R-Tree数据结构和R-Tree空间索引的算法描述,并从R-Tree索引技术的优缺点对R-Tree的改进结构--变种R-Tree进行了论述.最后,对R-Tree的最新 ...

最新文章

  1. 清华团队将Transformer用到3D点云分割
  2. Atitit 项目的主体设计与结构文档 v5
  3. pytorch 笔记: torch.nn.Embedding
  4. Python标准库:itertools迭代器函数
  5. 不用FTP使用SecureCRT上传下载文件,并解决rz、sz command not found异常
  6. 8051单片机指令和寻址方式
  7. 物联网无线数传通信模块:工业级高精度电源模块
  8. centos root密码_如何在CentOS中恢复丢失的root密码
  9. confirm的意思中文翻译_confirm的中文意思
  10. ActiveMQ简单介绍+简单实例
  11. 【Laravel】使用 Laravel Excel 实现 Excel/CSV 文件导入导出功能
  12. mysql清空数据库_mysql命令行快速清空数据库的方法
  13. 【已成功安装但无法使用】Python 3.10.2 安装pyodbc
  14. 802.11协议精读1:学习资料整理
  15. 周纪三 周慎靓王元年(辛丑,公元前320年)——摘要
  16. first season twenty-third episode,Ben was born!!!,Hi Ben???
  17. 微信小程序复用公众号资质快速认证
  18. 用网站代替p2p服务器,[视频]PURSUIT:互联网可摆脱对服务器的依赖 用P2P取代
  19. Linux 在bash.bashrc中添加 一个目录
  20. 完形填空生成器 1-1 打开文本框与提取文本字符

热门文章

  1. python学习之面对对象程序设计作业
  2. U盘中毒后文件夹变成exe怎么办
  3. 如何使用万用表测量二极管的阻值
  4. c语言怎么移位,C语言中的移位操作
  5. RNA二级结构系列(1):基础知识篇
  6. 数字图像分辨率的认识
  7. Linux防火墙配置工具iptables中MASQUERADE的含义
  8. C# 单个按钮实现暂停或继续
  9. 搭建完美的数学计算环境: iTeXmacs+maxima
  10. python数学公式编辑工具_GNU TeXmacs