一种高效的寻路算法 - B*寻路算法
2014-11-19 07:43
239 查看
在此把这个算法称作B* 寻路算法(Branch Star 分支寻路算法,且与A*对应),本算法适用于游戏中怪物的自动寻路,其效率远远超过A*算法,经过测试,效率是普通A*算法的几十上百倍。
通过引入该算法,一定程度上解决了游戏服务器端无法进行常规寻路的效率问题,除非服务器端有独立的AI处理线程,否则在服务器端无法允许可能消耗大量时间的寻路搜索,即使是业界普遍公认的最佳的A*,所以普遍的折中做法是服务器端只做近距离的寻路,或通过导航站点缩短A*的范围。
算法原理
本算法启发于自然界中真实动物的寻路过程,并加以改善以解决各种阻挡问题。
前置定义:
1、探索节点:为了叙述方便,我们定义在寻路过程中向前探索的节点(地图格子)称为探索节点,起始探索节点即为原点。(探索节点可以对应为A*中的开放节点)
2、自由的探索节点:探索节点朝着目标前进,如果前方不是阻挡,探索节点可以继续向前进入下一个地图格子,这种探索节点我们称为自由探索节点;
3、绕爬的探索节点:探索节点朝着目标前进,如果前方是阻挡,探索节点将试图绕过阻挡,绕行中的探索节点我们成为绕爬的探索节点;
算法过程
1、起始,探索节点为自由节点,从原点出发,向目标前进;
2、自由节点前进过程中判断前面是否为障碍,
a、不是障碍,向目标前进一步,仍为自由节点;
b、是障碍,以前方障碍为界,分出左右两个分支,分别试图绕过障碍,这两个分支节点即成为两个绕爬的探索节点;
3、绕爬的探索节点绕过障碍后,又成为自由节点,回到2);
4、探索节点前进后,判断当前地图格子是否为目标格子,如果是则寻路成功,根据寻路过程构造完整路径;
5、寻路过程中,如果探索节点没有了,则寻路结束,表明没有目标格子不可达;
演示如下:
![](http://dl.javaeye.com/upload/picture/pic/63917/9f8aebdc-1d29-3b24-8503-0a4c2f55df77.gif)
![](http://dl.javaeye.com/upload/picture/pic/63919/f1b052c3-e811-3020-8963-40a86c34ecd2.gif)
![](http://dl.javaeye.com/upload/picture/pic/63925/abdfd7cb-5bad-3a63-9c33-e6e9a9b667c8.gif)
![](http://dl.javaeye.com/upload/picture/pic/63923/8d7ccf80-c4c0-3fd3-bc49-69b1aea86dbe.gif)
![](http://dl.javaeye.com/upload/picture/pic/63921/75f501d8-6dec-3266-922b-514790a91437.gif)
B*与A*算法的性能比较
寻路次数比较(5秒钟寻路次数)
![](http://dl.javaeye.com/upload/picture/pic/70724/0e1c8a2f-273a-3dd0-a148-e0bedf7f96ca.gif)
B*与A*性能比较实例
1、 无障碍情况
此种情况,根据以上测试数据,B*算法效率是普通A*的44倍(左为A*,右为B*)
![](http://dl.javaeye.com/upload/picture/pic/63935/211d83ed-1c79-3208-a171-0dd076c0a302.gif)
![](http://dl.javaeye.com/upload/picture/pic/63927/2e342093-bbf8-384d-b2a6-8c4883a1a5c0.gif)
2、线形障碍
此种情况,根据以上测试数据,B*算法效率是普通A*的28倍(左为A*,右为B*)
![](http://dl.javaeye.com/upload/picture/pic/63941/5a1ca015-d81f-3283-89d3-b512d0c94f8c.gif)
![](http://dl.javaeye.com/upload/picture/pic/63933/bc007ab8-291f-3e03-b79d-0491656dd857.gif)
3、环形障碍
此种情况,根据以上测试数据,B*算法效率是普通A*的132倍(左为A*,右为B*)
![](http://dl.javaeye.com/upload/picture/pic/63931/1a47e78a-15e0-3d1c-af26-a37837119ef2.gif)
![](http://dl.javaeye.com/upload/picture/pic/63939/94a906fa-70ca-32e5-aed8-e48cfff5e4c0.gif)
4、封闭障碍(目标不可达)
此种情况,根据以上测试数据,B*算法效率是普通A*的581倍(左为A*,右为B*)
![](http://dl.javaeye.com/upload/picture/pic/63937/75004f42-0c05-39c0-96f4-47e88619b88b.gif)
![](http://dl.javaeye.com/upload/picture/pic/63929/1991d318-e47c-3953-8449-e953b7942eff.gif)
衍生算法
通过以上封闭障碍,可以看出,这个方法在判断地图上的两个点是否可达上,也是非常高效的,在不可达情况下,时间复杂度与封闭障碍的周长相当,而不是整个地图的面积。
通过引入该算法,一定程度上解决了游戏服务器端无法进行常规寻路的效率问题,除非服务器端有独立的AI处理线程,否则在服务器端无法允许可能消耗大量时间的寻路搜索,即使是业界普遍公认的最佳的A*,所以普遍的折中做法是服务器端只做近距离的寻路,或通过导航站点缩短A*的范围。
算法原理
本算法启发于自然界中真实动物的寻路过程,并加以改善以解决各种阻挡问题。
前置定义:
1、探索节点:为了叙述方便,我们定义在寻路过程中向前探索的节点(地图格子)称为探索节点,起始探索节点即为原点。(探索节点可以对应为A*中的开放节点)
2、自由的探索节点:探索节点朝着目标前进,如果前方不是阻挡,探索节点可以继续向前进入下一个地图格子,这种探索节点我们称为自由探索节点;
3、绕爬的探索节点:探索节点朝着目标前进,如果前方是阻挡,探索节点将试图绕过阻挡,绕行中的探索节点我们成为绕爬的探索节点;
算法过程
1、起始,探索节点为自由节点,从原点出发,向目标前进;
2、自由节点前进过程中判断前面是否为障碍,
a、不是障碍,向目标前进一步,仍为自由节点;
b、是障碍,以前方障碍为界,分出左右两个分支,分别试图绕过障碍,这两个分支节点即成为两个绕爬的探索节点;
3、绕爬的探索节点绕过障碍后,又成为自由节点,回到2);
4、探索节点前进后,判断当前地图格子是否为目标格子,如果是则寻路成功,根据寻路过程构造完整路径;
5、寻路过程中,如果探索节点没有了,则寻路结束,表明没有目标格子不可达;
演示如下:
![](http://dl.javaeye.com/upload/picture/pic/63917/9f8aebdc-1d29-3b24-8503-0a4c2f55df77.gif)
![](http://dl.javaeye.com/upload/picture/pic/63919/f1b052c3-e811-3020-8963-40a86c34ecd2.gif)
![](http://dl.javaeye.com/upload/picture/pic/63925/abdfd7cb-5bad-3a63-9c33-e6e9a9b667c8.gif)
![](http://dl.javaeye.com/upload/picture/pic/63923/8d7ccf80-c4c0-3fd3-bc49-69b1aea86dbe.gif)
![](http://dl.javaeye.com/upload/picture/pic/63921/75f501d8-6dec-3266-922b-514790a91437.gif)
B*与A*算法的性能比较
寻路次数比较(5秒钟寻路次数)
![](http://dl.javaeye.com/upload/picture/pic/70724/0e1c8a2f-273a-3dd0-a148-e0bedf7f96ca.gif)
B*与A*性能比较实例
1、 无障碍情况
此种情况,根据以上测试数据,B*算法效率是普通A*的44倍(左为A*,右为B*)
![](http://dl.javaeye.com/upload/picture/pic/63935/211d83ed-1c79-3208-a171-0dd076c0a302.gif)
![](http://dl.javaeye.com/upload/picture/pic/63927/2e342093-bbf8-384d-b2a6-8c4883a1a5c0.gif)
2、线形障碍
此种情况,根据以上测试数据,B*算法效率是普通A*的28倍(左为A*,右为B*)
![](http://dl.javaeye.com/upload/picture/pic/63941/5a1ca015-d81f-3283-89d3-b512d0c94f8c.gif)
![](http://dl.javaeye.com/upload/picture/pic/63933/bc007ab8-291f-3e03-b79d-0491656dd857.gif)
3、环形障碍
此种情况,根据以上测试数据,B*算法效率是普通A*的132倍(左为A*,右为B*)
![](http://dl.javaeye.com/upload/picture/pic/63931/1a47e78a-15e0-3d1c-af26-a37837119ef2.gif)
![](http://dl.javaeye.com/upload/picture/pic/63939/94a906fa-70ca-32e5-aed8-e48cfff5e4c0.gif)
4、封闭障碍(目标不可达)
此种情况,根据以上测试数据,B*算法效率是普通A*的581倍(左为A*,右为B*)
![](http://dl.javaeye.com/upload/picture/pic/63937/75004f42-0c05-39c0-96f4-47e88619b88b.gif)
![](http://dl.javaeye.com/upload/picture/pic/63929/1991d318-e47c-3953-8449-e953b7942eff.gif)
衍生算法
通过以上封闭障碍,可以看出,这个方法在判断地图上的两个点是否可达上,也是非常高效的,在不可达情况下,时间复杂度与封闭障碍的周长相当,而不是整个地图的面积。
相关文章推荐
- 一种高效的寻路算法 - B*寻路算法
- 一种高效的寻路算法 - B*寻路算法
- 一种高效的寻路算法——B*寻路算法
- 一种高效的寻路算法 - B*寻路算法
- 根据数据库表中记录自动构造一棵结构树的一种高效算法
- 一个无序整数数组,数组元素大于5个,请用一种高效的算法找出其中最大的5个值.
- 寻找链表中间节点-一种高效的算法
- 一种高效快速的高密度椒盐噪声消除算法(吕宗伟等)
- 一种简单、快速、高效的多边形减面算法
- 一种高效的求平均数的算法
- [iOS] 图像处理 - 一种高效裁剪图片圆角的算法
- 一个高效的a *寻路算法(八方向)
- 筛法:一种高效求解素数表的算法
- 寻找链表中间节点—一种高效的算法
- 寻找链表中间节点-一种高效的算法
- 一种安全、高效、简单的登陆算法
- 发现一种简单高效的Hash算法,比常用的几种算法效率高出一倍以上
- 计算两个时间戳之间的天数的一种比较高效的算法
- COBSforToN一种用于串行通讯的高效编码算法
- 一种高效算法---振动测量中振幅的计算方法