| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3826 人关注过本帖
标题:迷宫问题?
取消只看楼主 加入收藏
zjl138
Rank: 1
等 级:新手上路
威 望:1
帖 子:788
专家分:0
注 册:2007-11-12
收藏
 问题点数:0 回复次数:12 
迷宫问题?
下面是我写的一个迷宫,我用随机数产生迷宫,然后寻找出口,可是老是输出找不到出口,于是把迷宫改小,输出迷宫,用眼睛扫描了一下,有些是有出口的,但输出却是找不到出口,不得不怀疑程序错了,可是我找了半天,还是找不到。
呵呵,麻烦大家帮我看一下,哪里不行。有写个迷宫的朋友也可以把你的代码发上来,我自已研究。谢谢!!!
以下是我的代码:
[size=2]/********************************************************
** Highlight software by yzfy(雨中飞燕) http:// *
*********************************************************/
#include<iostream>
#include<ctime>
using namespace std;
const int m=5,p=5;                           //迷宫的行数和列数
struct offsets                                 //前进方向表的结构定义
{
    int a,b;                                  //a,b是x,y(SeekPath函数参数)方向的偏移
    char *dir;                                 //dir是方向
};
offsets move[8];                               //各个方向的偏移表
int Maze[m+2][p+2];                            //迷宫定义
int mark[m+2][p+2];                            //访问标记数组
int main()
{
    int SeekPath(int,int);
    int i,j;
    srand(unsigned(time(NULL)));

    offsets move[8]={{-1,0,"N"},{-1,1,"NE"},{0,1,"E"},{1,1,"SE"},
    {1,0,"SE"},{1,-1,"SW"},{0,-1,"W"},{-1,-1,"NW"}};
    for(i=0;i<m+2;i++)                               //用随机数产生为宫
    {
        for(j=0;j<p+2;j++)
            Maze[i][j]=rand()%2;
    }
    for(i=0;i<m+2;i++)                               //访问标记数组初始为零
        for(j=0;j<p+2;j++)
            mark[i][j]=0;
    cout<<"The maze is:"<<endl;                      //输出刚才产生的迷宫
    for(i=0;i<m+2;i++)
    {
        for(j=0;j<p+2;j++)
            cout<<Maze[i][j];
        cout<<endl;
    }
    mark[1][1]=1;                                     //从入口[1][1]开始
    if(SeekPath(1,1))                                 //调用求解迷宫的递归算法
        cout<<"("<<1<<","<<1<<"(,"<<"Direction"<<"E"<<endl;
    system("pause");
    return 0;
}
int SeekPath(int x,int y)
{
    //从迷宫某一位置开始,寻找通向出口[M][P]的一条路径。如果找到,返回1,否刚返回0;
    //试探的出发点为[1][1].
    int i,g,h;                                      //用G,H记录位置信息,DIR记方向
    char *d;
    if(x==m&&y==p)
        return 1;                                   //到达出口,返回1;
    for(i=0;i<8;i++)
    {
        g=x+move[i].a;               
        h=y+move[i].b;
        d=move[i].dir;                           //找下一位置和方向(a,b,dir)
        if(Maze[g][h]==0&&mark[g][h]==0)
        {
            mark[g][h]=1;
            if(SeekPath(g,h))                     //从此位置递归试探
            {
                cout<<"("<<g<<","<<h<<"),"<<"Direction"<<move[i].dir<<",";
                return 1;     //试探成功,逆向输出路径坐标
            }
        }
    }
    if(x==1&&y==1)
        cout<<"no path in Maze"<<endl;
    return 0;
}
[/size]

[[it] 本帖最后由 zjl138 于 2008-5-6 11:09 编辑 [/it]]
搜索更多相关主题的帖子: 迷宫 yzfy 眼睛 随机数 扫描 
2008-05-06 11:04
zjl138
Rank: 1
等 级:新手上路
威 望:1
帖 子:788
专家分:0
注 册:2007-11-12
收藏
得分:0 
怎么字体不能改小,这样会不会太难看了?

i like linux...
2008-05-06 11:07
zjl138
Rank: 1
等 级:新手上路
威 望:1
帖 子:788
专家分:0
注 册:2007-11-12
收藏
得分:0 
[bo]以下是引用 [un]雨中飛燕[/un] 在 2008-5-6 11:31 的发言:[/bo]

楼主的数组发生了坐标混乱的情况。。。。

http://blog.

谢谢,刚吃饭去了。我再看一下。
还有感谢你的代码。
谢谢!!!

i like linux...
2008-05-06 11:50
zjl138
Rank: 1
等 级:新手上路
威 望:1
帖 子:788
专家分:0
注 册:2007-11-12
收藏
得分:0 
还是不行,首先这里有误:offsets move[8]={{-1,0,"N"},{-1,1,"NE"},{0,1,"E"},{1,1,"SE"},
    {1,0,"SE"},{1,-1,"SW"},{0,-1,"W"},{-1,-1,"NW"}};
改为:
offsets move[8]={{-1,0,"N"},{-1,1,"NE"},{0,1,"E"},{1,1,"SE"},
    {1,0,"S"},{1,-1,"SW"},{0,-1,"W"},{-1,-1,"NW"}};
再调试,设断点,发现几个问题:
(1)mark[g][h]的值一直都是 1 。
(2)提示d,move[i]为错误指针。
我试着对g,h,d变量初始化,但还是一样的结果。
会不会是我的逻辑的问题,我自已发现不了,还望大伙帮忙。
谢谢!!!

[[it] 本帖最后由 zjl138 于 2008-5-6 13:32 编辑 [/it]]

i like linux...
2008-05-06 13:21
zjl138
Rank: 1
等 级:新手上路
威 望:1
帖 子:788
专家分:0
注 册:2007-11-12
收藏
得分:0 
谢谢楼上,我是没有标记边界。
我再改改。

i like linux...
2008-05-06 13:37
zjl138
Rank: 1
等 级:新手上路
威 望:1
帖 子:788
专家分:0
注 册:2007-11-12
收藏
得分:0 
还是一样,可能我对飞燕姐提醒的“数组越界”没理解清楚。
我已设了边界,并试了极端的方法,把迷宫初始为零。可结果还是一样,找不到迷宫出口。
飞燕姐有空帮我再看一下代码吗,不好意思,叫你看我的代码可能是件很痛苦的事,写得太乱了,呵呵。或者对我这个程序,选成数组越界的原因说详细一点。
/********************************************************
** Highlight software by yzfy(雨中飞燕) http:// *
*********************************************************/
#include<iostream>
#include<ctime>
using namespace std;
const int m=12,p=15;          //迷宫的行数和列数
struct offsets              //前进方向表的结构定义
{
    int a,b;              //a,b是x,y(SeekPath函数参数)方向的偏移
    char *dir;              //dir是方向
};
offsets move[8];           //各个方向的偏移表
int Maze[m+2][p+2];       //迷宫定义
int mark[m+2][p+2];      //访问标记数组
int main()
{
    int SeekPath(int,int);
    int i,j;
    srand(unsigned(time(NULL)));

    offsets move[8]={{-1,0,"N"},{-1,1,"NE"},{0,1,"E"},{1,1,"SE"},
    {1,0,"S"},{1,-1,"SW"},{0,-1,"W"},{-1,-1,"NW"}};
    for(i=0;i<m+2;i++)               //用随机数产生迷宫
    {
        for(j=0;j<=p+1;j++)
            Maze[i][j]=rand()%2;
    }
    //设定行边界
    for(j=0;j<=p+1;j++)
    {
        Maze[0][j]=Maze[m+1][j]=1;
    }
    //设定列边界
    for(i=0;i<=m+1;i++)
    {
        Maze[i][0]=Maze[i][p+1]=1;
    }
    for(i=0;i<m+2;i++)                 //访问标记数组初始为零
        for(j=0;j<p+2;j++)
            mark[i][j]=0;
    cout<<"The maze is:"<<endl;         //输出刚才产生的迷宫
    for(i=0;i<m+2;i++)
    {
        for(j=0;j<p+2;j++)
            cout<<Maze[i][j];
        cout<<endl;
    }
    mark[1][1]=1;                    //从入口[1][1]开始
   
    if(SeekPath(1,1))                //调用求解迷宫的递归算法
        cout<<"("<<1<<","<<1<<"(,"<<"Direction"<<"E"<<endl;
    system("pause");
    return 0;
}
int SeekPath(int x,int y)
{
    //从迷宫某一位置开始,寻找通向出口[M][P]的一条路径。
    //如果找到,返回1,否刚返回0;
    //试探的出发点为[1][1].
    int i,g=0,h=0;                    //用G,H记录位置信息,D记方向
    char *d=NULL;
    if(x==m&&y==p)
        return 1;                     //到达出口,返回1;
    for(i=0;i<8;i++)
    {
        g=x+move[i].a;               
        h=y+move[i].b;
        d=move[i].dir;         //找下一位置和方向(a,b,dir)
        if(Maze[g][h]==0 && mark[g][h]==0)
        {
            mark[g][h]=1;
            if(SeekPath(g,h))                  //从此位置递归试探
            {
                cout<<"("<<g<<","<<h<<"),"<<"Direction"<<d<<",";
                return 1            //试探成功,逆向输出路径坐标
            }
        }
    }
    if(x==1&&y==1)
        cout<<"no path in Maze"<<endl;
    return 0;
}


[[it] 本帖最后由 zjl138 于 2008-5-6 14:37 编辑 [/it]]

i like linux...
2008-05-06 14:35
zjl138
Rank: 1
等 级:新手上路
威 望:1
帖 子:788
专家分:0
注 册:2007-11-12
收藏
得分:0 
再想了一下,迷宫初始化为零都不行,那应该是mark[i][j]这个标记数组有地方不行了,调试也一直显示mark[g][h]=1;导致这里一直过不去:
if(Maze[g][h]==0 && mark[g][h]==0)
        {
            mark[g][h]=1;
            if(SeekPath(g,h))                  //从此位置递归试探
            {
                cout<<"("<<g<<","<<h<<"),"<<"Direction"<<d<<",";
                return 1            //试探成功,逆向输出路径坐标
可mark[g][h]怎么会一直都是1呢?
我试输出了offsets move[8],迷宫,都能正常输出。
调试时还是这样:
(1)mark[g][h]的值一直都是 1 。
(2)提示d,move[i]为错误指针

i like linux...
2008-05-06 15:11
zjl138
Rank: 1
等 级:新手上路
威 望:1
帖 子:788
专家分:0
注 册:2007-11-12
收藏
得分:0 
晕,非常感谢飞燕姐,让你帮我找这样的错,真委屈你了,呵呵。
能成功运行了。我在下楼把代码贴上来。为感谢大家,我明天再写一个非递归解迷宫的程序上来,供大家参考。不要到时又错误多多就好了,呵呵。。。
谢谢!!!

i like linux...
2008-05-06 16:23
zjl138
Rank: 1
等 级:新手上路
威 望:1
帖 子:788
专家分:0
注 册:2007-11-12
收藏
得分:0 
我的代码:可能丑陋了点,没办法,现在的水平就只有这样了。
/********************************************************
** Highlight software by yzfy(雨中飞燕) http:// *
*********************************************************/
#include<iostream>
#include<ctime>
using namespace std;
const int m=12,p=15;          //迷宫的行数和列数
struct offsets              //前进方向表的结构定义
{
    int a,b;              //a,b是x,y(SeekPath函数参数)方向的偏移
    char *dir;              //dir是方向
};
            
int Maze[m+2][p+2];       //迷宫定义
int mark[m+2][p+2];      //访问标记数组
//各个方向的偏移表
offsets move[8]={{-1,0,"N"},{-1,1,"NE"},{0,1,"E"},{1,1,"SE"},
    {1,0,"S"},{1,-1,"SW"},{0,-1,"W"},{-1,-1,"NW"}};
int main()
{
    int SeekPath(int,int);
    int i,j;
    srand(unsigned(time(NULL)));
    for(i=0;i<m+2;i++)               //用随机数产生迷宫
    {
        for(j=0;j<=p+1;j++)
            Maze[i][j]=rand()%2;
    }
    //设定行边界
    for(j=0;j<=p+1;j++)
    {
        Maze[0][j]=Maze[m+1][j]=1;
    }
    //设定列边界
    for(i=0;i<=m+1;i++)
    {
        Maze[i][0]=Maze[i][p+1]=1;
    }
    for(i=0;i<m+2;i++)                 //访问标记数组初始为零
        for(j=0;j<p+2;j++)
            mark[i][j]=0;
    cout<<"The maze is:"<<endl;         //输出刚才产生的迷宫
    for(i=0;i<m+2;i++)
    {
        for(j=0;j<p+2;j++)
            cout<<Maze[i][j];
        cout<<endl;
    }
    mark[1][1]=1;                    //从入口[1][1]开始
   
    if(SeekPath(1,1))                //调用求解迷宫的递归算法
        cout<<"("<<1<<","<<1<<"(,"<<"Direction"<<"E"<<endl;
    system("pause");
    return 0;
}
int SeekPath(int x,int y)
{
    //从迷宫某一位置开始,寻找通向出口[M][P]的一条路径。
    //如果找到,返回1,否刚返回0;
    //试探的出发点为[1][1].
    int i,g=0,h=0;                    //用G,H记录位置信息,D记方向
    char *d=NULL;
    if(x==m&&y==p)
        return 1;                     //到达出口,返回1;
    for(i=0;i<8;i++)
    {
        g=x+move[i].a;               
        h=y+move[i].b;
        d=move[i].dir;              //找下一位置和方向(a,b,dir)
        if(Maze[g][h]==0 && mark[g][h]==0)
        {
            mark[g][h]=1;
            if(SeekPath(g,h))              //从此位置递归试探
            {
                cout<<"("<<g<<","<<h<<"),"<<"Direction  "<<d<<endl;
                return 1;                //试探成功,逆向输出路径坐标
            }
        }
    }
    if(x==1&&y==1)
        cout<<"no path in Maze"<<endl;
    return 0;
}

i like linux...
2008-05-06 16:29
zjl138
Rank: 1
等 级:新手上路
威 望:1
帖 子:788
专家分:0
注 册:2007-11-12
收藏
得分:0 
非递归解法已出来,由于刚才递归解法中遇到的问题,在飞燕姐的帮肋下,已解决,所以写这个这少了很多麻烦,注意了几个问题,所以只要算法正确,就能写出来了。程序中还有不足之处,以后再优化了,一高兴就先把代码发上来了,呵呵。再次感谢飞燕姐。
这次输出的只是出口,是我自已设定的。为(12,15)。试了几十次,五次成功找到出口。代码如下:
/********************************************************
** Highlight software by yzfy(雨中飞燕) http:// *
*********************************************************/
#include<iostream>
#include<ctime>
#include<stack>
using namespace std;
//前进方向表的结构定义
struct offsets
{
    int a,b;          //a,b是方向的偏移
    char *dir;        //dir是方向
};
//栈中的三元组结构
struct items
{
    int x,y,dir;             //位置和前进方向序号
};
offsets move[8]={{-1,0,"N"},{-1,1,"NE"},{0,1,"E"},{1,1,"SE"},
    {1,0,"S"},{1,-1,"SW"},{0,-1,"W"},{-1,-1,"NW"}};
const int m=12,p=15;
int mark[m+2][p+2];
int Maze[m+2][p+2];
//输出迷宫路径操作的实现
    ostream& operator<<(ostream& os,items& item)
{
    return os<<item.x<<" ,"<<item.y<<" ,"<<item.dir<<endl;
}

int main()
{
    void path(int m,int p);              //寻找出口函数
    srand(unsigned(time(NULL)));
    int i,j;
    //用随机数产生迷宫
    for(i=0;i<m+2;i++)                 
        for(j=0;j<p+2;j++)
            Maze[i][j]=rand()%2;
    //初始化标记数组
    for(i=0;i<m+2;i++)
        for(j=0;j<p+2;j++)
            mark[i][j]=0;
    //设定行边界
    for(j=0;j<p+2;j++)
        Maze[0][j]=Maze[m+1][j]=1;
    //设定列边界
    for(i=0;i<m+2;i++)
        Maze[i][0]=Maze[i][p+1]=1;
    //输出迷宫
    for(i=0;i<m+2;i++)
    {
        for(j=0;j<p+2;j++)
            cout<<Maze[i][j];
        cout<<endl;
    }
    path(m,p);
    system("pause");
    return 0;
}
void path(int m,int p)
{
    int i,j,d,g,h;
    mark[1][0]=1;           //设置入口
    stack<items> st;
    items tmp;
    tmp.x=1;tmp.y=0;tmp.dir=2;
    st.push(tmp);
    //栈不空,持续走下去
    while(st.empty()==false)
    {
        st.pop();              //退栈
        i=tmp.x;j=tmp.y;d=tmp.dir;         //d为前进方向表下标
        while(d<8)
        {
            g=i+move[d].a;h=j+move[d].b; //找下一个位置
            if(g==m&&h==p)                //找到出口
            {
                //cout<<st;
                cout<<m<<"  "<<p<<endl;   //输出出口位置
                return ;
            }
            if(Maze[g][h]==0&&mark[g][h]==0)    //新的路径可通
            {
                mark[g][h]=1;                  //标记为已访问过
                tmp.x=i;
                tmp.y=j;
                tmp.dir=d;
                st.push(tmp);               //进栈
                i=g;j=h;d=0;   //移动到(G,H),在各方向试探
            }
            else
               
d++;           //试探下一个方向
        }
    }
    cout<<"no path in maze!"<<endl;
}


[[it] 本帖最后由 zjl138 于 2008-5-6 16:59 编辑 [/it]]

i like linux...
2008-05-06 16:58
快速回复:迷宫问题?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.029520 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved