• BFS寻路算法的实现


    关于BFS的相关知识由于水平有限就不多说了,感兴趣的可以自己去wiki或者其他地方查阅资料。

    这里大概说一下BFS寻路的思路,或者个人对BFS的理解:

    大家知道Astar的一个显著特点是带有启发函数,换句话说,Astar尝试以人的思维来去寻找一段路径。而BFS则没有这种聪明劲,他看起来更中规中矩,老实巴交,更像是机器人的风格。

    简单的说,BFS为了找到一条路径,他从起点开始,然后是身边的邻居,然后是邻居的邻居,一个一个的搜查,直到搜到终点(寻路成功),或者把整个地图搜索完(除非最后一个点就是终点,否则寻路失败)。

    可能乍看上去BFS真的比较笨,但是他也并没有笨的不着边际,因为他最多把整个地图都搜一遍,这样,对于一张有限的地图,他寻找一段路径所花的时间也是相对的有一个上限。

    但Astar则不同,Astar虽然看起来带有聪明劲,但是这种聪明只是一种自作聪明,有时候,对于一些设计特殊的地图,Astar要为自己的聪明付出很大的代价。比如带有半岛的地图。

    总体上看,Astar在障碍越少的情况下寻路越快,而BFS则比较平缓,不管障碍多少,他快慢幅度并不大。

    废话不多说,下面用代码来说明BFS的思路:

    01.public function tryFindPath(sx:int, sy:int, ex:int, ey:int):Boolean  
    02.{  
    03.    var start:uint = getTimer();  
    04.      
    05.    _startNode = _mapData.setStartNode(sx,sy);  
    06.    _endNode = _mapData.setEndNode(ex,ey);  
    07.      
    08.    if(_startNode == _endNode) return false;  
    09.    if(!_endNode.walkable) return false;  
    10.      
    11.    var i:uint=0;  
    12.    _startNode.f = i;  
    13.    var queue:MinHeap = new MinHeap(100);  
    14.    queue.Enqueue(_startNode);  
    15.    var neighbor:Node;  
    16.    var testedNodes:Dictionary = new Dictionary();  
    17.      
    18.    while(queue.size>0)  
    19.    {  
    20.        var testNode:Node = queue.Dequeue() as Node;  
    21.        i++;  
    22.        var x:int,y:int;  
    23.        for(var dx:int=-1;dx<=1;++dx)  
    24.        {  
    25.            x = testNode.x + dx;  
    26.            for(var dy:int=-1;dy<=1;++dy)  
    27.            {  
    28.                y = testNode.y+dy;  
    29.                neighbor = _mapData.getNode(x,y);  
    30.                if(!neighbor) continue;  
    31.                if(!neighbor.walkable) continue;  
    32.                if(testedNodes[neighbor]) continue;  
    33.                testedNodes[neighbor] = true;  
    34.                neighbor.parent = testNode;  
    35.                neighbor.f = i;  
    36.                if(neighbor == _endNode)  
    37.                {  
    38.                    return true;  
    39.                }  
    40.                  
    41.                queue.Enqueue(neighbor);  
    42.            }  
    43.        }  
    44.    }  
    45.    return false;  
    46.}

    这里并没有给出全部相关的源码,该方法只展示一个思路:

    _mapData是对一个二维网格地图数据做了一个封装,包括设置起始点,终点,根据索引获取节点等。

    Node是一个节点对象,他有xy的属性和一个f属性,跟Astar的代价属性类似。

    queue是一个最小堆,他保证f值越小的Node对象越靠近队列的顶部。

    testedNodes用来记录节点是否被搜寻过。

    其寻路过程为:

    1,将起点放入队列;

    2,弹出队列中的最小代价的节点,搜寻他周围的有效节点(即存在,可走,而且没有被检查过),设置代价值,和父节点,如果这个节点就是终点,那么寻路成功,否则将此节点放入队列,在检查下一个邻居节点,如果所有的邻居节点都不是终点则进入3;

    3,如果队列空了,那么说明所有的节点都检查过了,没有找到终点,否则继续2。

    BFS的这种平缓特性在有些时候看起来似乎可以弥补Astar的缺陷,比如我们想在长程情况下采用BFS而短程的时候用Astar,但是这并不总是合适的,因为Astar并不是因为路程长才耗时,而是因为地形复杂,而地形复杂又没有一个可以衡量的指标,只能人为的去判断,所以最多我们通过人为的配置来选择寻路的方式。

  • 相关阅读:
    TextBox 只有下划线
    can't find web control library(web控件库)
    DropDownListSalesAC”有一个无效 SelectedValue,因为它不在项目列表中。
    IDE、SATA、SCSI、SAS、FC、SSD 硬盘类型
    如何打印1px表格
    CSS控制打印 分页
    Virtual Server could not open its emulated Ethernet switch driver. To fix this problem, reenable the Virtual Server Emulated Et
    Xml中SelectSingleNode方法中的xpath用法
    热带水果莫入冰箱?水果存放冰箱大法
    探索Asp.net的Postback机制
  • 原文地址:https://www.cnblogs.com/regalys168/p/3599155.html
Copyright © 2020-2023  润新知