【更新】

稍微将A*算法进行修正,使用BFS(按F值对open表排序),另外,新增评估函数,用来测量当前点到终点的线段上的随机某一点是否是墙或已访问结点,是的话返回1,否则返回0。

function path_add_barrial_tracing(state, pt1, pt2)
local xabs, yabs = math.abs(pt1.x - pt2.x), math.abs(pt1.y - pt2.y)
if xabs == 0 or yabs == 0 then return 0 end
local xr, yr = math.ceil(math.random(1,xabs)), math.ceil(math.random(1,yabs))
local v = path_get_point(state, {x= xr, y= yr})
if v ~= 1 then return 1 else return 0 end
end

效果图:

-----------------------------------------------------

写在前面

看到过类似的将寻路算法可视化的文章。

寻思着将它们整合进游戏框架,总体上说,整合难度比较低。

实现思路

先前实现了TableLayout,设定长宽,可以均匀排布容器内各元素。题图中的方格也是这样的实现思路。

只实现了广度遍历BFS和深度遍历DFS,两者是经典的遍历算法。

书上一般采用open和closed两个表的方式,这里为了图简单,就用一张表实现了。图的结构二维矩阵表示,1表示未访问过,3、4表示起点和终点,2表示墙,6及以上表示访问过。那么每次访问只要将矩阵中的值标记下即可。

  • BFS是将当前访问方块的相邻未访问方块添加进表的末尾,每次从表头取出将要访问的方块。由于添加的方块要隔一段时间才能访问到,所以可能导致表的体积迅速增大。因此,BFS的效率比较差,它会遍历所有的方块,将它能够找到全局最优解。《后天》中的海水淹没城市也是BFS的体现。
  • DFS每次将当前方块的相邻未访问方块添加进表的头部,每次从表头取方块。所以与BFS不同,新添加的方块立马就被访问,故表的体积不会迅速增大。它能快速找到解,但不一定是全局最优解。生活中的闪电生长方式就是DFS。

两种算法只是对于表的添加方式不同,DFS是添加到头部,BFS是添加到尾部。

这里主要的难点在于,方块的颜色是渐变的,离起点(红色)近的呈黑色,远的呈天蓝色。计算方式是求任意点到起点的距离,然后根据HSL转换到RGB,HSL的色相是固定的,而亮度是可以调整的,从而实现渐变效果。

-------------------------------------------------

下面实现(伪)A*算法。

BFS和DFS方法都有缺点:BFS能找到全局最优,然而它需要将所有位置都访问一遍,耗时间;DFS快,但只是局部最优,且DFS如何挑选需展开的结点也没有明确规定。

A*对上述方式有了改进。A*给出了一个评估函数F。F=G+H。G是当前移动量,H是评估的待移动距离,两者总和是当前结节的评估值,当然,值越小,走这条路的可能性越大。

解决方法很简单:令G=累积的移动距离;令H=当前位置离终点的哈密顿距离。在展开结点的时候,对待选结点按F值排序,使F值最小的最先展开,从而节省时间。

A*的实现一般用open和closed表,它将open表中的结点按F排序,选代价最小的展开。也就是说,A*算法每一次将open表中的结点进行排序,而A*的展开方式类似于BFS。为什么是基于BFS?因为BFS产生的open表结点是当前已遍历结点的轮廓,这有点像最小生成树算法,从当前轮廓中挑选代价最小的结点进行展开。唯一影响A*效率的就是F的计算方法。

PS:由于偷懒,实现A*与上面的不同!上面是将open进行排序,而我只将当前结点的相邻结点进行排序,所以算法效果肯定没A*好。再者,本系列的目标是做GUI,算法可视化只是一个demo。

阶段性总结

A*算法的关键是设立一个评估函数,就如同阿法狗对局面的估计一样。它采用的其实类似于最小生成树的方式(把格子想成上下左右相连的图),只是最小生成树的挑选规则是确定的(路径长度确定),A*的挑选规则是不确定的(评估函数不精准)。这导致最小生成树产生最优解,而A*不一定能得到最优解。

http://zhuanlan.zhihu.com/p/25593280备份。

实现A星算法的更多相关文章

  1. POJ 2449 Remmarguts' Date (SPFA + A星算法) - from lanshui_Yang

    题目大意:给你一个有向图,并给你三个数s.t 和 k ,让你求从点 s 到 点 t 的第 k 短的路径.如果第 k 短路不存在,则输出“-1” ,否则,输出第 k 短路的长度. 解题思路:这道题是一道 ...

  2. 算法起步之A星算法

    原文:算法起步之A星算法 用途: 寻找最短路径,优于bfs跟dfs 描述: 基本描述是,在深度优先搜索的基础上,增加了一个启发式算法,在选择节点的过程中,不是盲目选择,而是有目的的选的,F=G+H,f ...

  3. Cocos2d-x 3.1.1 学习日志16--A星算法(A*搜索算法)学问

    A *搜索算法称为A星算法.这是一个在图形平面,路径.求出最低通过成本的算法. 经常使用于游戏中的NPC的移动计算,或线上游戏的BOT的移动计算上. 首先:1.在Map地图中任取2个点,開始点和结束点 ...

  4. A*搜寻算法(A星算法)

    A*搜寻算法[编辑] 维基百科,自由的百科全书 本条目需要补充更多来源.(2015年6月30日) 请协助添加多方面可靠来源以改善这篇条目,无法查证的内容可能会被提出异议而移除. A*搜索算法,俗称A星 ...

  5. Java开源-astar:A 星算法

    astar A星算法Java实现 一.适用场景 在一张地图中,绘制从起点移动到终点的最优路径,地图中会有障碍物,必须绕开障碍物. 二.算法思路 1. 回溯法得到路径 (如果有路径)采用“结点与结点的父 ...

  6. A星算法(Java实现)

    一.适用场景 在一张地图中.绘制从起点移动到终点的最优路径,地图中会有障碍物.必须绕开障碍物. 二.算法思路 1. 回溯法得到路径 (假设有路径)採用"结点与结点的父节点"的关系从 ...

  7. JAVA根据A星算法规划起点到终点二维坐标的最短路径

    工具类 AStarUtil.java import java.util.*; import java.util.stream.Collectors; /** * A星算法工具类 */ public c ...

  8. AStar A* A星 算法TypeScript版本

    一 演示效果 二  参考教程 <ActionScript3.0 高级动画教程> + 源码 http://download.csdn.net/download/zhengchengpeng/ ...

  9. 基于HTML5的WebGL呈现A星算法3D可视化

    http://www.hightopo.com/demo/astar/astar.html 最近搞个游戏遇到最短路径的常规游戏问题,一时起兴基于HT for Web写了个A*算法的WebGL 3D呈现 ...

  10. 基于HTML5的WebGL呈现A星算法的3D可视化

    http://www.hightopo.com/demo/astar/astar.html 最近搞个游戏遇到最短路径的常规游戏问题,一时起兴基于HT for Web写了个A*算法的WebGL 3D呈现 ...

随机推荐

  1. 汇编之 eax, ebx, ecx, edx, esi, edi, ebp, esp??

    一般寄存器:AX.BX.CX.DXAX:累积暂存器,BX:基底暂存器,CX:计数暂存器,DX:资料暂存器 索引暂存器:SI.DISI:来源索引暂存器,DI:目的索引暂存器 堆叠.基底暂存器:SP.BP ...

  2. char与unsigned char的区别

    #include <stdio.h> int main() { unsigned ; char b = a; printf("a = %d , b = %d",a,b) ...

  3. Linux系统 vi/vim文本编辑器

    Linux系统 vi/vim文本编辑器 (一)Vim/Vi简介 (二)Vim/Vi工作模式 (三)Vim/Vi基本使用 (四)Vim/Vi应用技巧 (一)Vim/Vi简介 Vim/Vi是一个功能强大的 ...

  4. [洛谷P2066]机器分配

    题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M≤15,N≤10.分 ...

  5. Android应用开发-Activity

    Android四大组件:Activity,Service,Broadcast Receiver,Content Provider Activity是Context的子类,同时实现了Window.Cal ...

  6. 工具使用-----Jmeter教程 简单的压力测试

    摘抄于http://www.cnblogs.com/TankXiao/p/4059378.html 以下是英文版的,中文版的也差不多的 Jmeter是一个非常好用的压力测试工具.  Jmeter用来做 ...

  7. Java程序员面试中的多线程问题1

    转自:http://blog.jobbole.com/18571/ 很多核心Java面试题来源于多线程(Multi-Threading)和集合框架(Collections Framework), 理解 ...

  8. org.hibernate.QueryException: JPA-style positional param was not an integral ordinal; nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: JPA-style positional param w

    org.hibernate.QueryException: JPA-style positional param was not an integral ordinal; nested excepti ...

  9. C++并发编程 条件变量 condition_variable,线程安全队列示例

    1. 背景 c++11中提供了对线程与条件变量的更好支持,对于写多线程程序方便了很多. 再看c++并发编程,记一下学习笔记. 2. c++11 提供的相关api 3.1 wait wait用于无条件等 ...

  10. 【ZH奶酪】为什么Python不需要函数重载?

    函数重载的作用是什么? 函数重载主要是为了解决两个问题 可变参数类型 可变参数个数 另外,一个基本的设计原则是,仅仅当两个函数除了参数类型和参数个数不同以外,其功能是完全相同的,此时才使用函数重载,如 ...