B-Star寻路算法进阶剖析(数据结构+思路拓宽)

关于b星算法的初步了解,可以从以下文章入手
一种高效的寻路算法 - B*寻路算法
我们了解到了b星算法的基本思路就是贪心思想+攀爬障碍,本文从数据结构方面(以c#为例)和算法思路的重新整理回顾b星算法。

个人编写的c#实现的b星算法(正常方法的两个ui版本):https://download.csdn.net/download/Koweico/12574032

一、正常b星算法相关数据结构
正常b星算法:一步一步前进,遇到障碍则多条路径同时前进,利用判断语句判断是否撞过墙和方向判断方法来确定下一步的位置。
1.存储地图和障碍,以及遍历历史。
我们可以采用传统的二维int类型数组或者二维bool类型数组。

public bool[,] mymap;
public bool[,] visit;

2.存储遇到障碍物产生的分支路径点。
利用队列的先进先出原则,使得路径依次进队,当所有路径应该前进时,则依次出队,进行下一步的探索,死路则不再进队,直至队空则是无路可走,或是直至行至终点。

public Queue<bpoint> bpointqueue =new Queue<bpoint>();

3.方向的数据结构
利用枚举类型判断方向

public static short[] directioncolumn = { 1, 0, -1, 0 };
public static short[] directionrow = { 0, 1, 0, -1 };
// 0右   1下    2左   3上

4.路径点的数据结构
我们在每一个路径点里需要存储:这个点的父路径点;这个点的坐标;以及标记是否撞过墙或是撞过的墙的位置;还有分支方向。

public class bpoint
    {
        public int pointcolumn, pointrow, step;
        public short walldirection, direction;
        public bpoint daddy;
   }

5.路径点的初始化和操作
由于要不断构造新的路径点并且进行操作,为了解决命名和变量使用,可以将所有的路径点合为一个字典,利于路径点的操作,同时也能统计数量。

public Dictionary<int,bpoint> allpoint=new Dictionary<int,bpoint>();    
public int i = 0;                                                        //字典初始化

//使用范例
bpointqueue.Enqueue(allpoint[i]);
allpoint[i].walldirection = 0;
i++;

具体方法操作不一一列出,下载即可查看,完成效果:
gdi ui 版本:
B-Star寻路算法进阶剖析(数据结构+思路拓宽)_第1张图片
B-Star寻路算法进阶剖析(数据结构+思路拓宽)_第2张图片
button类 版本:
B-Star寻路算法进阶剖析(数据结构+思路拓宽)_第3张图片
B-Star寻路算法进阶剖析(数据结构+思路拓宽)_第4张图片
算法对比方面和之前的博客中大同小异,可通过 常见寻路算法演示 直观感受。

二、思路拓宽和个人拙见
1.算法是基于贪心思想的,所以当前的数据结构仍未解决出现凹形的包围状障碍物会出现无法找到通路的情况
B-Star寻路算法进阶剖析(数据结构+思路拓宽)_第5张图片
但是可以通过修改障碍物的数据结构,就可以完成这一目标。
方案:
将障碍物的数据结构改为闭合的矢量图形,即在初始化地图的时候障碍物周围的节点会被激活节点类中的链式变量,也就是为这些节点增加了顺时针节点和逆时针节点,这两个节点类的变量会指导路径的探索,成为两条分支队列分别继续探索,从而使得路径队列顺利的攀爬过这个凹形的包围状障碍物。
顺时针:
B-Star寻路算法进阶剖析(数据结构+思路拓宽)_第6张图片
逆时针:
B-Star寻路算法进阶剖析(数据结构+思路拓宽)_第7张图片
模拟效果:
B-Star寻路算法进阶剖析(数据结构+思路拓宽)_第8张图片
方案缺点:使得障碍物的初始化过程更加复杂,应该会占用更多空间,而且构造障碍物时间会更长,但是寻路时间却可能减少,这是因为有了顺时针逆时针矢量的存在,使得下一步有可能已经被提前规划好,综合来看,也就是花了更多的空间解决了这个问题。

2.B* 算法强大之处在于速度(抛开刚刚解决的障碍物问题),这也使得这个算法同最佳优先搜索一样,有可能找到的路径不是最短的路径。
要解决这个问题也可以,加入一个走回路的标记,当路径开始回头走时,标记激活,当不再回头或者已经超过了回头的路程时标记记录下这个点,再使用A* 算法优化起点和这个点之间的路径,使得路径是最短,但是这样其实很费时,就丢失了这个算法的强大之处。
另一个个人想法是利用多线程操作来进行策略选择,分配给不同的cpu分别进行A* 算法和B* 算法,同样也进行回头标记,但是不做更多操作,B* 算法会先完成,若没有回过头,则直接结束两个线程,返回B* 路线,如果有回过头,则等待A* 算法得到路线。

今后若有学余时间,会着手尝试实现提到的方案。

提到的A*算法,个人感觉很强的文章:堪称最好的A*算法(转)

你可能感兴趣的:(算法,数据结构,B*,寻路算法,b星,bstart,b*,寻路算法,C#项目源码)