关于智能寻路算法的研究,A-Star算法拓展,B星寻路算法

B星算法的原理图:

以下是C语言的一段源码

#ifndef __ASTARPATHFINDER_H__
#define __ASTARPATHFINDER_H__

#include "cocos2d.h"

USING_NS_CC;

/**
 * 横向移动一格的路径评分
 */
static const int COST_HORIZONTAL = 20;

/**
 * 竖向移动一格的路径评分
 */
static const int COST_VERTICAL = 5;

/**
 * 斜向移动一格的路径评分
 */
static const int COST_DIAGONAL = 12;

class PathInfo;

/**
 * A星寻路类
 * @author hpking
 *
 */
class AStarPathFinder
{
	// 未探索的节点列表
    cocos2d::CCArray* _openSteps;
	// 已探索的,不需要再寻路的节点列表
    cocos2d::CCArray* _closedSteps;

	// 地图相关数据
	PathInfo* _pathInfo;

public:
	AStarPathFinder(PathInfo* info);
	virtual ~AStarPathFinder();

    /**
     * public 寻路
     *
     * @param CCPoint startPoint tile开始坐标点
     * @param CCPoint endPoint tile结束坐标点
     * @return CCArray* 读取方法:CCPointFromString ( string->getCString() )
     */
    CCArray* find( CCPoint startTilePt, CCPoint endTilePt );

private:
	// 最短路径步数
	class ShortestPathStep : public cocos2d::CCObject
	{
	public:
		bool initWithPosition( cocos2d::CCPoint pos )
		{
			bool bRet = false;

			do
			{
				position = pos;
				gScore = 0;
				hScore = 0;
				parent = NULL;
				inOpen = false;
				inClose = false;

				bRet = true;
			}
			while ( 0 );

			return bRet;
		}

		int fScore()
		{
			return this->getGScore() + this->getHScore();
		}

		inline bool operator==( const ShortestPathStep* other )
		{
			return isEqual( other );
		}

		bool isEqual( const ShortestPathStep* other )
		{
			return this->getPosition().equals ( other->getPosition() );
		}

		static ShortestPathStep* inst( cocos2d::CCPoint pos )
		{
			AStarPathFinder::ShortestPathStep* sps = new AStarPathFinder::ShortestPathStep;

			if ( sps && sps->initWithPosition ( pos ) )
			{
				sps->autorelease();
				return sps;
			}

			CC_SAFE_DELETE ( sps );
			return NULL;
		}

		CC_SYNTHESIZE( cocos2d::CCPoint, position, Position );
		CC_SYNTHESIZE( int, gScore, GScore );
		CC_SYNTHESIZE( int, hScore, HScore );
		CC_SYNTHESIZE( ShortestPathStep*, parent, Parent );
		CC_SYNTHESIZE( bool, inOpen, InOpen );
		CC_SYNTHESIZE( bool, inClose, InClose );

	private:
		cocos2d::CCString* description()
		{
			return CCString::createWithFormat ( "pos = [%f, %f], g=%d, h=%d, f=%d", this->getPosition().x, this->getPosition().y, this->getGScore(), this->getHScore(), this->fScore() );
		}
	};

private:
    void destroyLists();

    CCArray* createPath( ShortestPathStep* step );//int xStart, int yStart
    
	void findAndSort( ShortestPathStep* step );

	void insertAndSort( ShortestPathStep* step );

    /**
     * private  判断是否超出边界或路点是否可走
     *
     * @param CCPoint tpt 
     * @return bool 
     */
    bool isWalkable( CCPoint tpt );

    /**
     * private  计算G值
     *
     * @param Node * curNode
     * @param Node * node
     * @return int
     */
    int getGValue( ShortestPathStep* curStep, ShortestPathStep* step );

    /**
     * private  计算H值
     *
     * @param Node * curNode
     * @param Node * endNode
     * @param Node * node
     * @return int
     */
    int getHValue( ShortestPathStep* curStep, ShortestPathStep* endStep, ShortestPathStep* step );

    cocos2d::CCArray* getAroundsNode( CCPoint tPt );

	bool isInClosed(CCPoint tPt);

    void setOpenSteps ( cocos2d::CCArray* var );
    void setClosedSteps ( cocos2d::CCArray* var );
    void setShortestPath ( cocos2d::CCArray* var );
};

#endif





#include "AStarPathFinder.h"
#include "map/PathInfo.h"

AStarPathFinder::AStarPathFinder( PathInfo* info )
{
    _pathInfo = info;
    _openSteps = NULL;
    _closedSteps = NULL;
}

AStarPathFinder::~AStarPathFinder()
{
    destroyLists();
}

// 获取毫秒时间
long msNow()
{
	struct cc_timeval now;
	CCTime::gettimeofdayCocos2d( &now, NULL );
	return ( now.tv_sec * 1000 + now.tv_usec / 1000 );
}

CCArray* AStarPathFinder::find( CCPoint startTilePt, CCPoint endTilePt )
{
    bool isFinded = false; //能否找到路径,true-已找到

    // 到达终点
    if ( startTilePt.equals ( endTilePt ) )
    {
        CCLog ( "You‘re already there! :P" );
        return NULL;
    }

    // 终点不可走,直接退出(可优化为最近的可走地点停止)
    if ( !isWalkable( endTilePt ) )
    {
        CCLog ( "blocked! :P" );
        return NULL;
    }

    // 设置打开和封闭步数
    setOpenSteps ( CCArray::create() );
    setClosedSteps ( CCArray::create() );

    //CCLog ( "From:(%f, %f) To(%f, %f)", startTilePt.x, startTilePt.y, endTilePt.x, endTilePt.y );

    // 结束坐标
    ShortestPathStep* endStep = ShortestPathStep::inst ( endTilePt );

    // 插入开始点
    insertAndSort ( ShortestPathStep::inst ( startTilePt ) );

    ShortestPathStep* curStep;
    long time1 = msNow();

    do
    {
        // 取出并删除开放列表第一个元素
        curStep = ( ShortestPathStep* ) _openSteps->objectAtIndex ( 0 );
        curStep->setInClose( true );
        curStep->setInOpen( false );
        _closedSteps->addObject ( curStep );
        _openSteps->removeObjectAtIndex ( 0 );

        // 当前节点==目标节点
        if ( curStep->getPosition().equals( endTilePt ) )
        {
            isFinded = true; //能达到终点,找到路径
            break;
        }

        // 取相邻八个方向的节点,去除不可通过和已在关闭列表中的节点
        CCArray* aroundNodes  = getAroundsNode ( curStep->getPosition() );
        //CCLog("8 dirc %d",aroundNodes->count());
        CCObject* obj;
        CCARRAY_FOREACH ( aroundNodes, obj )
        {
            // 计算 G, H 值
            CCString* string = ( CCString* ) obj;
            ShortestPathStep* nextStep = new ShortestPathStep;
            nextStep->initWithPosition ( CCPointFromString ( string->getCString() ) );

            int g = getGValue ( curStep , nextStep );
            int h = getHValue ( curStep , endStep , nextStep );

            if ( nextStep->getInOpen() ) // 如果节点已在播放列表中
            {
                // 如果该节点新的G值比原来的G值小,修改F,G值,设置该节点的父节点为当前节点
                if ( g < nextStep->getGScore() )
                {
                    nextStep->setGScore( g );
                    nextStep->setHScore( h );
                    nextStep->setParent( curStep );
                    findAndSort ( nextStep );
                    nextStep->release();
                }
            }
            else // 如果节点不在开放列表中
            {
                // 插入开放列表中,并按照估价值排序
                nextStep->setGScore( g );
                nextStep->setHScore( h );
                nextStep->setParent( curStep );

                insertAndSort ( nextStep );
                nextStep->release();
            }

            //CCLog("open num:%d",_openSteps->count());
        }
    }
    while ( _openSteps->count() > 0 );

    CCLog( "a* time:%d", msNow() - time1 );

    /*if( _openSteps )
    CCLog( "finded:%d, openlen %d, closelen %d", isFinded ? 1 : 0, _openSteps->count(), _closedSteps->count() );*/

    // 找到路径
    if ( isFinded )
    {
        CCArray* path = createPath ( curStep );

        destroyLists ();

        return path;
    }
    else // 没有找到路径
    {
        destroyLists ();

        return NULL;
    }
}

void AStarPathFinder::destroyLists()
{
    CC_SAFE_RELEASE_NULL ( _openSteps );
    CC_SAFE_RELEASE_NULL ( _closedSteps );
}

CCArray* AStarPathFinder::createPath( ShortestPathStep* step )//int xStart, int yStart
{
    CCArray* path = CCArray::create();

    CCString* str;

    do
    {
        if ( step->getParent() != NULL )
        {
            str = CCString::createWithFormat ( "{%f, %f}", step->getPosition().x, step->getPosition().y );
            path->insertObject ( str, 0 );
        }

        step = step->getParent();
    }
    while ( step != NULL );

    return path;
}

void AStarPathFinder::findAndSort( ShortestPathStep* step )
{
    unsigned int count = _openSteps->count();

    if ( count < 1 )
        return;

    int stepFScore = step->fScore();

    for ( unsigned int i = 0; i < count; i++ )
    {
        ShortestPathStep* sps = ( ShortestPathStep* ) _openSteps->objectAtIndex ( i );

        if ( stepFScore <= sps->fScore() )
            _openSteps->insertObject ( step, i );

        if ( step->getPosition().equals( sps->getPosition() ) )
            _openSteps->removeObjectAtIndex( i );
    }
}

void AStarPathFinder::insertAndSort( ShortestPathStep* step )
{
    step->setInOpen( true );

    int stepFScore = step->fScore();
    unsigned int count = _openSteps->count();

    if( count == 0 )
        _openSteps->addObject( step );
    else
    {
        for ( unsigned int i = 0; i < count; i++ )
        {
            ShortestPathStep* sps = ( ShortestPathStep* ) _openSteps->objectAtIndex ( i );

            if ( stepFScore <= sps->fScore() )
            {
                _openSteps->insertObject ( step, i );
                return;
            }
        }
    }
}

bool AStarPathFinder::isWalkable( CCPoint tPt )
{
    // 1. 是否是有效的地图上点(数组边界检查)
    if ( tPt.x < _pathInfo->startPt.x || tPt.x >= _pathInfo->iCol )
        return false;

    if ( tPt.y < _pathInfo->startPt.y || tPt.y >= _pathInfo->iRow )
        return false;

    // 2. 是否是walkable
    return _pathInfo->isWalkable( tPt );
}

/**
 * private  计算G值
 *
 * @param ShortestPathStep * curStep
 * @param ShortestPathStep * step
 * @return int
 */
int AStarPathFinder::getGValue( ShortestPathStep* curStep, ShortestPathStep* step )
{
    int g  = 0;

    if ( curStep->getPosition().y == step->getPosition().y ) // 横向  左右
    {
        g = curStep->getGScore() + COST_HORIZONTAL;
    }
    else if ( curStep->getPosition().y + 2 == step->getPosition().y || curStep->getPosition().y - 2 == step->getPosition().y ) // 竖向  上下
    {
        g = curStep->getGScore() + COST_VERTICAL * 2;
    }
    else // 斜向  左上 左下 右上 右下
    {
        g = curStep->getGScore() + COST_DIAGONAL;
    }

    return g;
}

/**
 * private  计算H值
 *
 * @param ShortestPathStep * curStep
 * @param ShortestPathStep * endStep
 * @param ShortestPathStep * step
 * @return int
 */
int AStarPathFinder::getHValue( ShortestPathStep* curStep, ShortestPathStep* endStep, ShortestPathStep* step )
{
    if ( curStep == NULL || endStep == NULL || step == NULL )
        return 0;

    // 节点到0,0点的x轴距离
    int to0  = step->getPosition().x * COST_HORIZONTAL + ( ( int )step->getPosition().y & 1 ) * COST_HORIZONTAL / 2;

    // 终止节点到0,0点的x轴距离
    int endTo0  = endStep->getPosition().x * COST_HORIZONTAL + ( ( int )endStep->getPosition().y & 1 ) * COST_HORIZONTAL / 2;

    return abs ( ( float )endTo0 - ( float )to0 ) + abs ( ( float )endStep->getPosition().y - ( float )step->getPosition().y ) * COST_VERTICAL;
}

cocos2d::CCArray* AStarPathFinder::getAroundsNode( CCPoint tPt )
{
    CCArray* aroundNodes = CCArray::create();

    /// 菱形组合的地图八方向与正常不同

    // 左
    CCPoint p = CCPointMake ( tPt.x - 1, tPt.y );
    CCString* str;

    if ( isWalkable ( p ) && !isInClosed( p ) ) // 可走并且不在关闭列表
    {
        str = CCString::createWithFormat ( "{%f, %f}", p.x, p.y );
        //CCLOG( "left=%s", str->getCString() );
        aroundNodes->addObject ( str );
    }

    // 右
    p = CCPointMake ( tPt.x + 1, tPt.y );

    if ( isWalkable ( p ) && !isInClosed( p ) )
    {
        str = CCString::createWithFormat ( "{%f, %f}", p.x, p.y );
        // CCLOG( "right=%s", str->getCString() );
        aroundNodes->addObject ( str );
    }

    // 上
    p = CCPointMake ( tPt.x, tPt.y - 2 );  // -2

    if ( isWalkable ( p ) && !isInClosed( p ) )
    {
        str = CCString::createWithFormat ( "{%f, %f}", p.x, p.y );
        //CCLOG( "up=%s", str->getCString() );
        aroundNodes->addObject ( str );
    }

    // 下
    p = CCPointMake ( tPt.x, tPt.y + 2 );// + 2

    if ( isWalkable ( p ) && !isInClosed( p ) )
    {
        str = CCString::createWithFormat ( "{%f, %f}", p.x, p.y );
        //CCLOG( "down=%s", str->getCString() );
        aroundNodes->addObject ( str );
    }

    // 左上
    p = CCPointMake ( tPt.x - 1 + ( ( int )tPt.y & 1 ), tPt.y - 1 );

    if ( isWalkable ( p ) && !isInClosed( p ) )
    {
        str = CCString::createWithFormat ( "{%f, %f}", p.x, p.y );
        //CCLOG( "leftUp=%s", str->getCString() );
        aroundNodes->addObject ( str );
    }

    // 左下
    p = CCPointMake ( tPt.x - 1 + ( ( int )tPt.y & 1 ), tPt.y + 1 );

    if ( isWalkable ( p ) && !isInClosed( p ) )
    {
        str = CCString::createWithFormat ( "{%f, %f}", p.x, p.y );
        //CCLOG( "leftDown=%s", str->getCString() );
        aroundNodes->addObject ( str );
    }

    //右上
    p = CCPointMake ( tPt.x + ( ( int )tPt.y & 1 ), tPt.y - 1 );

    if ( isWalkable ( p ) && !isInClosed( p ) )
    {
        str = CCString::createWithFormat ( "{%f, %f}", p.x, p.y );
        //CCLOG( "rightUp=%s", str->getCString() );
        aroundNodes->addObject ( str );
    }

    //右下
    p = CCPointMake ( tPt.x + ( ( int )tPt.y & 1 ), tPt.y + 1 );

    if ( isWalkable ( p ) && !isInClosed( p ) )
    {
        str = CCString::createWithFormat ( "{%f, %f}", p.x, p.y );
        //CCLOG( "rightDown=%s", str->getCString() );
        aroundNodes->addObject ( str );
    }

    return aroundNodes;
}

bool AStarPathFinder::isInClosed( CCPoint pt )
{
    CCObject* temp;
    CCARRAY_FOREACH ( _closedSteps, temp )
    {
        ShortestPathStep* sps = ( ShortestPathStep* ) temp;

        if( sps->getPosition().equals( pt ) )
        {
            return true;
        }
    }

    return false;
}

void AStarPathFinder::setOpenSteps ( cocos2d::CCArray* var )
{
    if ( _openSteps != var )
    {
        CC_SAFE_RELEASE_NULL ( _openSteps );
        CC_SAFE_RETAIN ( var );
        _openSteps = var;
    }
}

void AStarPathFinder::setClosedSteps ( cocos2d::CCArray* var )
{
    if ( _closedSteps != var )
    {
        CC_SAFE_RELEASE_NULL ( _closedSteps );
        CC_SAFE_RETAIN ( var );
        _closedSteps = var;
    }
}

void AStarPathFinder::setShortestPath ( cocos2d::CCArray* var )
{
    /*if ( shortestPath != var )
    {
    CC_SAFE_RELEASE_NULL ( shortestPath );
    CC_SAFE_RETAIN ( var );
    shortestPath = var;
    }*/
}

-----------------------------------------------------------为此我做了一个各种算法时间的效率对比

---------------------------------------------------------------关于B星和B星算法的加强版C星算法的使用,强调的是速度而不是种类繁多的花样。---------------------------------------------------------------

言归正传,以下我做了一些测试工具(仅仅是测试)

				
时间: 2024-09-29 22:44:03

关于智能寻路算法的研究,A-Star算法拓展,B星寻路算法的相关文章

A星寻路算法以及C++实现

A星寻路算法真是我一生接触的第一个人工智能算法了... A星寻路算法显然是用来寻路的,应用也很普遍,比如梦幻西游...算法的思路很简单,就是在bfs的基础上加了估值函数. 它的核心是 F(x) = G(x) + H(x) 和open.close列表: G(x)表示从起点到X点的消耗(或者叫移动量什么的),H(X)表示X点到终点的消耗的估值,F(x)就是两者的和值.open列表记录了可能要走的区域,close列表记录了不会再考虑的区域.我们每次都选F值最小的区域搜索,就能搜到一条到终点的最短路径,

智能算法的研究与实现

目前计算机中的搜索算法有哪些? 深度优先,广度优先(源自于数据结构) 穷举法(列出所有可能),回溯法(深度优先思想加上返回式搜索)源自于算法设计与分析 爬山法,模拟退火,遗传算法(智能化算法)都是一些自适应的随机搜索算法,(有点类似于不确定性算法,也是一些启发式算法(另外蚁群算法也是启发式算法) 梯度下降算法(源自于最优化理论) 遗传算法该如何理解 从启发式的角度去理解更容易: 遗传算法参照达尔文的进化论,认为物种都是向好的方向去发展(适者生存),因此可以认为到足够的代数之后,得到的最值可实际的

车道线检测文献解读系列(一) 基于机器视觉的高速车道标志线检测算法的研究_李晗

作者背景 基于机器视觉的高速车道标志线检测算法的研究_李晗 东北大学车辆工程硕士学位论文 2006年 [GB/T 7714]李晗. 基于机器视觉的高速车道标志线检测算法的研究[D]. 东北大学, 2006. DOI:10.7666/d.y852642.` 论文结构一览 预处理 灰度化 [亮点]模式判别 选择日间模式还是夜间模式: 在每个检测周期开始时,首先判断采用日间模式还是夜间模式工作.摄像机视野中的上半部分为天空背景,天空亮度可以显著区分日间和夜间环境.由于天空的颜色为蓝离,日间天空的蓝色分

人工智能在近年来智能医疗上的研究问题整理

人工智能在近年来智能医疗上的研究问题整理 智能医疗的现状是什么?为什么还没有太大突破? 现状:在美國,医疗系統近年來最关注的是成本.效率.和政策(比如ObamaCare) 問題.智能的话题大都在边缘领域造声势,至今并未全面和直接改变大医院系统的操作运行.但是今年的RSNA(北美放射年会)的开门主题是智能化.所以这个话題还会执续升温.但是请记住:任何智能系統必須与"降成本,提效率,順政策"挂上钩,才能有希望达到快速的成功. 人工智能在近几年很多行业应用中有了很大的突破, 同以往相比,突破

优化的对比度增强算法用于有雾图像的清晰化处理(算法效果是我目前看到最为稳定的,且对天空具有天然的免疫力,极力推荐有需要的朋友研究)。

在未谈及具体的算法流程前,先贴几幅用该算法处理的效果. 不知道各位对这个算法的效果第一印象如何. 这个算法的原理来自于文章<Optimized contrast enhancement for real-time image and video dehazing>,作者是韩国人. 这个算法也是基于大气散射模型: 和现在一些常见的去雾文章有明显的不同的是,这篇文章的并不是基于暗通道原理的,也不是把重点强调在透射率图的细化上,而是提出了一种新的得到粗透射率图的方法.并且文章分别讲到了静态图像和视频

算法复杂度,及三种主要排序算法的研究

一.时间复杂度 1.时间频度  T(n),n为问题的规模 即--算法中语句的执行次数.又叫语句频度. 2.时间复杂度 记作 O( f(n) ),这里的f(n)是一个T(n)的同数量级函数. 如O(1)表示算法的语句执行次数为一个常数,不随规模n的增长而增长: 又如T(n)=n^2+3n+4与T(n)=4n^2+2n+1它们的频度不同, 但时间复杂度相同,都为O(n^2). 3.算法的性能 主要用算法的 时间复杂度 的数量级来评价一个算法的时间性能. 二.空间复杂度 S(n),包括3方面: 1.算

用简单直白的方式讲解A星寻路算法原理

很多游戏特别是rts,rpg类游戏,都需要用到寻路.寻路算法有深度优先搜索(DFS),广度优先搜索(BFS),A星算法等,而A星算法是一种具备启发性策略的算法,效率是几种算法中最高的,因此也成为游戏中最常用的寻路算法. 直入正题: 在游戏设计中,地图可以划分为若干大小相同的方块区域(方格),这些方格就是寻路的基本单元. 在确定了寻路的开始点,结束点的情况下,假定每个方块都有一个F值,该值代表了在当前路线下选择走该方块的代价.而A星寻路的思路很简单:从开始点,每走一步都选择代价最小的格子走,直到达

A星寻路算法-(入门级)

你是否在做一款游戏的时候想创造一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢? 如果是的话,请看这篇教程,我们会展示如何使用A星寻路算法来实现它! 在网上已经有很多篇关于A星寻路算法的文章,但是大部分都是提供给已经了解基本原理的高级开发者的. 本篇教程将从最基本的原理讲起.我们会一步步讲解A星寻路算法,幷配有很多图解和例子. 不管你使用的是什么编程语言或者操作平台,你会发现本篇教程很有帮助,因为它在非编程语言的层面上解释了算法的原理. 现在找下到达一杯咖啡因饮料和美味的零食的最

菜鸟福利 A星寻路算法 cocos2d-x实现

这篇blog是翻译自iOS Tutorial Team的成员 Johann Fradj,他目前是一位全职的资深iOS开发工程师.他是HotApps Factory的创始人,该公司开发了AppCooker 你是否在做一款游戏的时候想实现一种寻路算法,让一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢? 如果是的话,请看这篇教程,我们会展示如何使用著名的A星寻路算法来实现它! 公式表示为: f(n)=g(n)+h(n), 其中 f(n)是从初始点经由节点n到目标点的估价函数, g(n