工作中需要优化A*算法,研究了一天,最后取得了不错的效果。看网上的朋友还没有相关的研究,特此记录一下。有错误欢迎大家批评指正。如需转载请注明出处,http://www.cnblogs.com/Leonhard-/p/6842052.html,这是对作者最起码的尊重,谢谢大家。

本文结构如下:

一、A*算法优化背景介绍

二、A*算法介绍与实现简述

三、深入思考优化需求

  1.启发函数的设计思路

  2.启发函数与cost值的相对关系

  3.启发函数中对k值大小的深入思考

四、总结

一、A*算法优化背景介绍

  A*算法运用的场景很广泛,不同的运用场景有不同的A*设计思路,本文不是描述所有环境下的设计思路,而仅是记录工作中碰到的A*算法优化思路。使用的背景是在一个二维地图上,角色允许从周围的八个方向进行移动(如下图,角色在粉红色位置,周围蓝色位置为可走路线),地图中带有障碍物,求从某一个点到另外一个点的静态路径。具体的要求:1.让这个路径尽可能的短;2.让移动更加平滑,尽可能少的出现角色在选择方向上的抖动(后文有进一步介绍)。

二、A*算法介绍与实现简述

1.A*算法简单介绍

  网上已经有朋友发了短小精干却内容清晰的A*算法教程,没有研究过A*算法的朋友可以先到这个链接学习基本A*算法(如果想进一步了解A*算法的种种相关信息,可以查看原版链接或者翻译版链接)。此处则不再对重复的信息进行复制粘贴。

2.工作当中的A*算法实现思路。

  大概思路是这样的,代码用的是一个heap来存储open队列节点,用一个哈希表来存储close队列(当然也可以使用其他的方法,上述给的链接里有讲,本文就不再赘述)。

三、深入思考优化需求

1.估值函数的设计思路

其中估值函数如下:

1 int estimateValue(Point gaol,Point current)
2 {
3     int dx = abs(goal.x-current.x);
4     int dy = abs(goal.y-current.y);
5     if(dx > dy)
6          return 10*dx+4*dy;
7     else
8          return 10*dy+4*dx;
9 }

  以dx>dy的情况为例,其中的10*dx+4*dy是什么意思呢?如下图,粉红色为需要考虑估值的点,棕色为终点,其中棕色线条的长度*10则为估值函数的估计值(放大10倍是为了去掉小数点),即10*(dx+0.4*dy)。

  

2.估值函数与cost值的相对关系

  为了说明角色往不同方向移动的cost值,我们给图的格子标上数字,方便说明,如下图。公司代码中设定,往2,4,5,7方向移动,cost值为1,往1,3,6,8位置移动,则cost值为2。细心的朋友会发现,这个地方有了错误。上述我们为了将1位小数的浮点数转换为整数,把estimate值乘了个系数10,此处也应该乘以10。即往2,4,5,7方向移动,cost值为10,往1,3,6,8位置移动,则cost值为20。根据以往的习惯,1.当目的地在位置3时,我们鼓励玩家直接从粉红点跳到3;2.当目的地点在位置5右边一个格子时,我们鼓励玩家先到5,然后再移动到5右边的格子。如果往斜方向上移动的取值为20的话,我们发现会出现一个问题,就是从粉红点直接到3的cost等于先到5再到3的cost值,这样会引起移动时角色的“抖动”(角色经常在面向3和面向5的两个方向中切换,看起来就像在抖动);如果我们把往斜方向上移动的取值为10的话,这样斜方向上和水平方向上又有了新问题,因为从粉红色格子到3再到5右边的格子的cost值等于粉红色格子先到5再到5右边格子的cost值,这样看起来比较奇怪,当地图比较大时,会更明显,当角色要从地图左下角到右下角时,角色先到地图中间的最上方,然后又往右下角进行前进,而且会增加角色的“抖动”。那么往斜方向上移动的cost值的取值范围最好是属于(10,20),这里假设我们取14,后面介绍这会出现的问题。

  

  为什么会出现角色抖动呢,分析以上我们可以知道,当estimate+cost值相等的时候,维护open队列的heap只能随机取一个,所以不能保证取出来的就一定是按我们想要的某一个方向前进的节点。那解决思路是什么呢,就是estimate+cost值尽量少的出现相等的情况,要么就是修改heap读取的方式,一目了然,前者才是个好方法。而上面的cost取值为14,经过计算我们发现,往右上方移动与往右边移动的estimate+cost的值相等,也会出现“抖动”。而此时我们将往斜上方移动的cost值取(10,14)或者(14,20),问题圆满解决了。那么往斜上方移动的cost值取(10,14)或者(14,20)有什么区别呢?看图来说明。

  当我们取(10,14)时,寻路结果如下:

  当我们取(14,20)的话,寻路结果如下:

  结合上面的两幅图,我们清楚了cost值和dy系数(后文称为k)之间的关系(只考虑dx>dy的情况,dy>dx情况类似)。当斜方向与水平方向的cost的插值大于k时,寻路会优先往x方向走,一直走到dx == dy时候开始走斜线,反之则先走斜线,后走水平线。

3.估值函数中的k值的深入思考

  上一小节我们讨论了估值函数中的k值和往斜上方走的cost值的相对关系,那么我们进一步思考,这个k值是否可以随便取呢。答案:是,但也不全是。为什么这么说呢?具体的k值对性能和速度有很大影响,如果k的选取让estimate<=从该点到目标节点的实际cost值,那么它能取到最优解,但是也因为estimate+cost的值较小的原因,heap考虑的节点数变多,让算法的速度减慢;反之,如果k的选取让estimate>从该点到目标节点的实际cost值,那么它不一定取到最优解,此时A*算法便不再是A*算法,沦为了Greedy first-search algorithm,因为estimate+cost的值较大的原因,heap考虑的节点数变少,让算法的速度加快,但是也不能保证最优解了。所以,为了取到最优解,k的值不能大于4。

四、总结

  本文介绍了二维地图上A*算法的估值函数的设计思路并讨论了它与cost值的相对关系及其影响。综上所述,二维地图上为了保证让角色走最短路径,且让角色尽量不出现“抖动”,那么估值函数设计为 G = 10*dx + 4*dy就比较好。而且考虑到项目组的游戏地图为矩形如下图(黄色),建筑物的俯视图如下图(黑色),先往水平方向走比先往斜方向走好看,所以往斜上方走的cost值取(14,20)比较好。

转载于:https://www.cnblogs.com/Leonhard-/p/6842052.html

寻路优化(一)——二维地图上A*启发函数的设计探索相关推荐

  1. maptalks+three.js+vue webpack项目实现二维地图上贴三维模型

    我们不是走在坑里就是走在前往坑的路上_(:зゝ∠)_ 最终效果如图:(地图上添加一个"三维地图"的toolbar按钮,点击后在二维地图上贴上建好的三维模型点击显示弹框) 以下都在已 ...

  2. unity三维地图的经纬度如何在二维地图上表示_安全数据分析:数据点—地图—线性回归...

    一次性进群,长期免费索取教程,没有付费教程. 教程列表见微信公众号底部菜单 进微信群回复公众号:微信群:QQ群:460500587 微信公众号:计算机与网络安全 ID:Computer-network ...

  3. unity三维地图的经纬度如何在二维地图上表示_接入C++版本recastnavigation寻路库到Unity/服务端中...

    前言 因为Unity版本的更新迭代,老版本的A*插件在新版本Unity已经无法正常使用,包括一些运行时代码也已经过时,重新接入要花费很多时间,干脆接入一个新的寻路方案吧. 这里选择的是久负盛名的htt ...

  4. unity三维地图的经纬度如何在二维地图上表示_三维GIS与游戏引擎的跨界融合,打造数字化孪生的平行世界...

    ▲点击关注,收获更多GIS精彩 游戏地图在游戏中起基础和关键作用,它承载游戏中的各种资源,是游戏系统中非常重要的组成部分(图1),所以游戏通常具有明显的地理意义.因此,虽然三维GIS与游戏引擎是两个不 ...

  5. 二维地图展示爆管分析

    作者:doremi 管线系统管理目前大多数都是使用三维客户端来实现的,爆管分析也是在三维客户端上展示的.但是最近有很多客户的来电询问如何在二维地图上实现管线的一些分析功能.因此,本文将介绍如何在二维地 ...

  6. 二维地图性能优化(一)

    二维地图性能优化(一) 开发工具与关键技术: SuperMap iDesktop 9D.SuperMap GIS撰写时间:2020年5月16日 今天,我要和大家分享的技术是二维地图性能优化. 在我们的 ...

  7. 用字节数组存放二维地图数据

    一 二维地图数据内容 在RPG的大地图中,我们往往会分割成很多小块(逻辑上),用于玩家行走,比如使用A星寻路等等,就需要的二维地图数据.一般情况,存放的是数值,主要是指每个格子里的数值,这里的数值是指 ...

  8. cad图形如何导入到奥维地图_【详细教程】奥维地图上查看项目的线路图或平面图...

    我们新到一个工地项目,一般都需要知道道路的走向,或者项目的所在位置,这个时候我们一般使用测量仪器将相关点位测量出来以进行查看.但是这种方法耗时较长.效率较低. 那如何提高效率呢? 这里我们就使用到了奥 ...

  9. 如何生成gazebo仿真环境的二维地图真值

    在移动机器人仿真中,二维地图真值可以用来评价slam建图结果,也可以直接给路径规划算法提供输入. 利用gazebo进行仿真时,有很多方法都可以获取静态仿真环境的二维地图真值,本文将对以下链接: hyf ...

最新文章

  1. Dialog 带白色的边的处理方法
  2. 大厂前实习生被威胁,“关闭开源项目,不然就告你”
  3. 随机森林采用多数表决的一种,最终表决结果不是树上的类别(class)频率,而是树上的各类别概率的平均值
  4. php 缺少参数,php - 如何验证JSON响应中是否缺少参数-Laravel 6 - 堆栈内存溢出
  5. 湖大和厦大计算机专硕6,【图片】一战厦大计算机上岸,经验帖。慢更【考研吧】_百度贴吧...
  6. 谈谈java中遍历Map的几种方法
  7. Machine Learning(Stanford)| 斯坦福大学机(吴恩达)器学习笔记【汇总】
  8. Java开发者必备:超全的Java问题排查工具单
  9. android最优化启动画面,Android启动页黑屏及最优解决方案
  10. Atitit 图像处理之理解卷积attilax总结
  11. 【字体】编程常用字体推荐,微软,苹果,开源系统默认代码字体
  12. 10种流行的Java框架
  13. 微信小程序自定义状态栏组件,提取自(colorui)
  14. 计算机地图制图原理与算法,计算机地图制图原理与算法基础.ppt
  15. accesskey属性:激活元素快捷键(Alt+)
  16. Unsupervised Question Answering by Cloze Translation
  17. 【算法】剑指offer-删除链表中重复的节点最小栈
  18. 12月18日23点,2022年卡塔尔世界杯决赛,阿根廷对阵法国,上演巅峰对决,谁能捧走大力神杯?
  19. 如何在Java中转换Excel文件到图像?
  20. eNSP实验三:OSPF路由协议

热门文章

  1. $.post 中文乱码 php,如何解决jquery $.post 乱码问题
  2. ionic4 中使用 url scheme 插件 点击链接打开app
  3. 鸿蒙系统受谷歌影响吗,华为鸿蒙系统,会受到人们的欢迎吗?
  4. set 有序吗js_2021了,你的vue实践够熟练了吗?源码思维呢?
  5. eclipse项目里javascript总是验证,且出现最多的error是 Description Resource Path Location Type Syntax error on toke
  6. Linux删除安卓温控,RK平台关闭温度控制降频功能
  7. oracle12图书馆,Oracle图书馆管理系统
  8. php gpg,使用 gpg 验证 php
  9. terminal mysql 停止_转载MySQL之终端(Terminal)管理MySQL
  10. 可燃气体浓度多少合格_科普:气体容积单位LEL%、VOL%、TLV(ppm)之间如何换算?...