网页功能: 加入收藏 设为首页 网站搜索  
四种寻路算法并比较
发表日期:2006-09-03作者:[转贴] 出处:  

好久没搞这些东西了...想了十分钟才勉强回忆起来...
写了三个钟头...好累啊...
四种算法是DFS,BFS,Heuristic DFS, Heuristic BFS (A*)
用了两张障碍表,一张是典型的迷宫:

char Block[SY][SX]=
{{1,1,1,1,1,1,1,1,1,1,1 },
{1,0,1,0,1,0,0,0,0,0,1 },
{1,0,1,0,0,0,1,0,1,1,1 },
{1,0,0,0,1,0,1,0,0,0,1 },
{1,0,1,1,0,0,1,0,0,1,1 },
{1,0,1,0,1,1,0,1,0,0,1 },
{1,0,0,0,0,0,0,0,1,0,1 },
{1,0,1,0,1,0,1,0,1,0,1 },
{1,0,0,1,0,0,1,0,1,0,1 },
{1,1,1,1,1,1,1,1,1,1,1 }};

第二张是删掉一些障碍后的:

char Block[SY][SX]=
{{1,1,1,1,1,1,1,1,1,1,1 },
{1,0,1,0,1,0,0,0,0,0,1 },
{1,0,1,0,0,0,1,0,1,1,1 },
{1,0,0,0,0,0,1,0,0,0,1 },
{1,0,0,1,0,0,1,0,0,1,1 },
{1,0,1,0,0,1,0,1,0,0,1 },
{1,0,0,0,0,0,0,0,1,0,1 },
{1,0,1,0,0,0,1,0,1,0,1 },
{1,0,0,1,0,0,1,0,0,0,1 },
{1,1,1,1,1,1,1,1,1,1,1 }};

结果:
尝试节点数 合法节点数 步数
深度优先 416/133 110/43 19/25
广度优先 190/188 48/49 19/15
深度+启发 283/39 82/22 19/19
广度+启发 189/185 48/49 19/15

所以可以看出深度+启发是最好的,效率高路径也挺短。A*第一是不真实二是慢三是空间消耗较大。

附:dfs+heu的源程序,bc++ 3.1通过

#include <iostream.h>
#include <memory.h>
#include <stdlib.h>

#define SX 11 //宽

#define SY 10 //长


int dx[4]={0,0,-1,1}; //四种移动方向对x和y坐标的影响

int dy[4]={-1,1,0,0};

/*char Block[SY][SX]= //障碍表
{{ 1,1,1,1,1,1,1,1,1,1,1 },
{ 1,0,1,0,1,0,0,0,0,0,1 },
{ 1,0,1,0,0,0,1,0,1,1,1 },
{ 1,0,0,0,0,0,1,0,0,0,1 },
{ 1,0,0,1,0,0,1,0,0,1,1 },
{ 1,0,1,0,0,1,0,1,0,0,1 },
{ 1,0,0,0,0,0,0,0,1,0,1 },
{ 1,0,1,0,0,0,1,0,1,0,1 },
{ 1,0,0,1,0,0,1,0,0,0,1 },
{ 1,1,1,1,1,1,1,1,1,1,1 }};*/


char Block[SY][SX]= //障碍表

{{ 1,1,1,1,1,1,1,1,1,1,1 },
{ 1,0,1,0,1,0,0,0,0,0,1 },
{ 1,0,1,0,0,0,1,0,1,1,1 },
{ 1,0,0,0,1,0,1,0,0,0,1 },
{ 1,0,1,1,0,0,1,0,0,1,1 },
{ 1,0,1,0,1,1,0,1,0,0,1 },
{ 1,0,0,0,0,0,0,0,1,0,1 },
{ 1,0,1,0,1,0,1,0,1,0,1 },
{ 1,0,0,1,0,0,1,0,1,0,1 },
{ 1,1,1,1,1,1,1,1,1,1,1 }};

int MaxAct=4; //移动方向总数

char Table[SY][SX]; //已到过标记

int Level=-1; //第几步

int LevelComplete=0; //这一步的搜索是否完成

int AllComplete=0; //全部搜索是否完成

char Act[1000]; //每一步的移动方向,搜索1000步,够了吧?

int x=1,y=1; //现在的x和y坐标

int TargetX=9,TargetY=8; //目标x和y坐标

int sum1=0,sum2=0;

void Test( );
void Back( );
int ActOK( );
int GetNextAct( );

void main( )
{
    memset(Act,0,sizeof(Act)); //清零

    memset(Table,0,sizeof(Table));
    Table[y][x]=1; //做已到过标记

    while (!AllComplete) //是否全部搜索完

    {
        Level++;LevelComplete=0; //搜索下一步

        while (!LevelComplete)
        {
            Act[Level]=GetNextAct( ); //改变移动方向

            if (Act[Level]<=MaxAct)
                sum1++;
            if (ActOK( )) //移动方向是否合理

            {
                sum2++;
                Test( ); //测试是否已到目标

                LevelComplete=1; //该步搜索完成

            }
            else
            {
                if (Act[Level]>MaxAct) //已搜索完所有方向

                    Back( ); //回上一步

                if (Level<0) //全部搜索完仍无结果

                    LevelComplete=AllComplete=1; //退出

            }
        }
    }
}

void Test( )
{
    if ((x==TargetX)&&(y==TargetY)) //已到目标

    {
        for (int i=0;i<=Level;i++)
            cout<<(int)Act[i]; //输出结果

        cout<<endl;
        cout<<Level+1<<" "<<sum1<<" "<<sum2<<endl;
        LevelComplete=AllComplete=1; //完成搜索

    }
}

int ActOK( )
{
    int tx=x+dx[Act[Level]-1]; //将到点的x坐标

    int ty=y+dy[Act[Level]-1]; //将到点的y坐标

    if (Act[Level]>MaxAct) //方向错误?

        return 0;
    if ((tx>=SX)||(tx<0)) //x坐标出界?

        return 0;
    if ((ty>=SY)||(ty<0)) //y坐标出界?

        return 0;
    if (Table[ty][tx]==1) //已到过?

        return 0;
    if (Block[ty][tx]==1) //有障碍?

        return 0;
    x=tx;
    y=ty; //移动

    Table[y][x]=1; //做已到过标记

    return 1;
}

void Back( )
{
    x-=dx[Act[Level-1]-1];
    y-=dy[Act[Level-1]-1]; //退回原来的点

    Table[y][x]=0; //清除已到过标记

    Act[Level]=0; //清除方向

    Level--; //回上一层

}

int GetNextAct( ) //找到下一个移动方向。这一段程序有些乱,

//仔细看!

{
    int dis[4];
    int order[4];
    int t=32767;
    int tt=2;
    for (int i=0;i<4;i++)
    dis[i]=abs(x+dx[i]-TargetX)+abs(y+dy[i]-TargetY);
    for (i=0;i<4;i++)
    if (dis[i]<t)
    {
        order[0]=i+1;
        t=dis[i];
    }
    if (Act[Level]==0)
        return order[0];
    order[1]=-1;
    for (i=0;i<4;i++)
    if ((dis[i]==t)&&(i!=(order[0]-1)))
    {
        order[1]=i+1;
        break;
    }
    if (order[1]!=-1)
    {
        for (i=0;i<4;i++)
            if (dis[i]!=t)
            {
                order[tt]=i+1;
                tt++;
            }
    }
    else
    {
        for (i=0;i<4;i++)
        if (dis[i]!=t)
        {
            order[tt-1]=i+1;
            tt++;
        }
    }

    if (Act[Level]==order[0])
        return order[1];
    if (Act[Level]==order[1])
        return order[2];
    if (Act[Level]==order[2])
        return order[3];
    if (Act[Level]==order[3])
        return 5;
}

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 四种寻路算法并比较
本类热点文章
  A*寻路算法(For 初学者)
  A*寻路初探 GameDev.net
  用有限状态机实现的迷宫求解
  计算机中随机数的产生
  精美的随机数生成器程序
  即时战略游戏中如何协调对象移动
  计算几何算法概览
  飞行射击游戏中的碰撞检测
  电脑AI浅谈
  五子棋算法探讨
  小谈网络游戏同步
  五子棋算法
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00397