自动寻路算法(A*算法)分享

一、为什么地图网格化?
位置描述:
鼠标位置使用像素坐标描述。
地图位置使用经度纬度描述。
为了方便描述地图上元素的位置,将地图网格化。

二、什么是曼哈顿距离?
曼哈顿距离(Manhattan distance):两点在南北方向上的距离加上在东西方向上的距离,即D(I,J)=|XI-XJ|+|YI-YJ|。
计算曼哈顿距离时,忽略两点之间的障碍物。
若有两点(1,2)和(3,4),则曼哈顿距离 = |3 -1| + |4 - 2| = 4

三、A*算法涉及的名词
开启列表:存放即将进行分析的可达位置。
关闭列表:存放已经分析完毕的可达位置。
估价函数:f(n) = g(n) + h(n)
f(n) 是从初始点经由节点n到目标点的估价函数。
g(n) 是在地图中从初始节点到n节点的实际代价 h(n) 是从n到目标节点最佳路径的估计代价。
h(n)是估计代价,可以使用曼哈顿距离作为估计代价。

四、A*算法步骤
1、将起始位置放入开启列表。
2、获取开启列表中F(n) 值(经由点n的估价值)最小的位置,且曼哈顿距离最小,作为当前位置。
3、判断当前位置是否为终点,若为终点,将终点放入关闭列表并执行第八步。
4、将当前位置从开启列表中移除,并放入关闭列表。
5、获取当前位置可达的位置。注意:关闭列表中的位置不可达。
6、将当前位置可达的位置放入开启列表。
7、若开启列表不为空,则从第二步继续循环。
8、若终点存在关闭列表,则返回路径,否则未找到路径。

五、A*算法优化
1、地图粒度没必要划分到像素点。像素点的划分粒度对于搜索来说代价太高。
      建议划分的粒度在不影响使用的情况下取最大值。
2、每次新位置放入开启列表时,给列表排序(建议选择快速排序算法),
      这样每次从开启列表取位置时,只取第一个位置即可。
      这种方式适用于超大地图,分支节点多的地图。
3、可以前进到相邻的对角线上的位置(8个方向)。建议使用8方向而非4方向。
      相邻对角线上位置的代价建议为1.4。
4、不同位置的损耗。在地图中,位置有两种状态,可通过和不可通过。
      但有的可通过位置可能移动代价更高,比如,堵车道路上的位置。
5、对于超级大的地图寻路,可以把大地图划分为N个小区域。先使用A*算法
      在N个小区域里找到路径,在路径上的每个小区域里再次使用A*算法找到
      最终的路径。
6、Dijkstra(狄克斯特拉)算法:该算法与A*算法区别在于估价函数, Dijkstra 算法
      没有h(n)。Dijkstra 算法每次迭代时选择的下一个顶点是标记点之外距离源点最
      近的顶点。但由于dijkstra算法主要计算从源点到其他所有点的最短路径,所以
      算法的效率较低。
      对于多个目标位置,建议采用Dijkstra算法。比如停车场有多个出口,需要找到离
      当前位置最近的出口。

-=各种=-寻路算法演示:
http://qiao.github.io/PathFinding.js/visual/

猜你喜欢

转载自871656094.iteye.com/blog/2355341