当前位置:文档之家› 迷宫问题c++实验报告

迷宫问题c++实验报告

数据结构实验报告班级:姓名:学号:组员:问题描述:迷宫实验是取自心理学的一个古典实验。

在该实验中,把一只老鼠从一个无顶大盒子的门放入,在盒中设置了许多墙,对行进方向形成了多处阻挡。

盒子仅有一个出口,在出口处放置一块奶酪,吸引老鼠在迷宫中寻找道路以到达出口。

对同一只老鼠重复进行上述实验,一直到老鼠从入口到出口,而不走错一步。

老鼠经多次试验终于得到它学习走迷宫的路线。

设计功能要求:迷宫由m行n列的二维数组设置,0表示无障碍,1表示有障碍。

设入口为(1,1),出口为(m,n),每次只能从一个无障碍单元移到周围四个方向上任一无障碍单元。

编程实现对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。

算法输入:代表迷宫入口的坐标算法输出:穿过迷宫的结果。

算法要点:创建迷宫,试探法查找路任务分派为了达到锻炼大家独立设计算法的能力,大家一致决定,先自己独立设计算法,不论算法的好坏、难易,完完全全出自于自己的手中。

在大家独立完成算法后,进行小组集中讨论,将自己的算法思想与大家交流,特别是自己最自豪的部分或是自己觉得可以改进的地方,之后得出最优结果。

独立设计求解思想:利用递归的方式进行求解。

从入口出发,按某一方向向前探索,若能走通(未走过的),即某处可以到达,则到达新点,否则试探下一方向;若所有的方向均没有通路,则沿原路返回前一点,换下一个方向再继续试探,直到所有可能的通路都探索到,或找到一条通路,或无路可走又返回到入口点。

如果现在位置(i,j)处于迷宫的边界位置,则有2种或3种可能的走法,为使问题简单化,用maze[m+2][n+2]来表示迷宫,而迷宫的四周的值全部为1,这样做使问题简单了,每个点的试探方向全部为4,不用再判断当前点的试探方向有几个,同时与迷宫周围是墙壁这一实际问题相一致。

struct Pos{int x,y;int di;};其中x、y分别表示横纵坐标值、di表示前进的方向。

在已经某一位置(i, j, d)的情况下,其下一个位置横、纵坐标的取值如表4-2所示。

而走到一个新位置时,其方向值初始置为1。

代码#include "iostream"#include "iomanip"using namespace std;struct Pos{int x,y;int di;};typedef Pos ElemType;struct StackNode{ElemType data;struct StackNode *next;};class LinkStack{private:StackNode *top;public:LinkStack();//无参构造函数~LinkStack();//析构函数void ClearStack();//将栈清空bool Push(ElemType x); //进栈bool Pop(ElemType &x);//出栈bool GetTop(ElemType &x);//取栈顶元素bool StackEmpty(); //判断栈是否为空栈int StackLength(); //栈的长度};LinkStack::LinkStack(){top=NULL;}LinkStack::~LinkStack(){StackNode *p;while(top!=NULL){p=top;top=top->next;delete p;}}bool LinkStack::StackEmpty(){if(!top)return true;return false;}int LinkStack::StackLength(){StackNode *p=top;int count=0;while(p){count++;p=p->next;}return count;}bool LinkStack::Push(ElemType x) {StackNode *p;p=new StackNode;p->data=x;p->next=top;top=p;return true;}bool LinkStack::Pop(ElemType& x) {if(StackEmpty())return false;else{StackNode *p=top;x=top->data;top=top->next;delete p;return true;}}bool LinkStack::GetTop(ElemType &x) {if(StackEmpty())return false;x=top->data;return true;}#define M 6+2#define N 6+2class Maze{int MazeArray[M][N];Pos start,end;public:Maze(int array[][N-2]);bool FindPath();void PrintPath();void SetStart(int x=1,int y=1);void SetEnd(int x=M-2,int y=N-2);Pos NextPos(Pos &curp);void Mark(Pos &curp);void DeadPos(Pos &curp);bool isEnd(Pos &curp);bool canPass(Pos &curp);void PrintMaze();};void Maze::Mark(Pos &curp){MazeArray[curp.x][curp.y]=-1;}bool Maze::canPass(Pos &curp){if(MazeArray[curp.x][curp.y]==0)return true;elsereturn false;}void Maze::DeadPos(Pos &curp){MazeArray[curp.x][curp.y]=2;}bool Maze::isEnd(Pos &curp){if(curp.x==end.x && curp.y==end.y) return true;return false;}void Maze::SetStart(int x,int y){start.x=x; start.y=y;}void Maze::SetEnd(int x,int y){end.x=x; end.y=y;}Maze::Maze(int array[][N-2]){//加围墙int i,j;for(i=0;i<M;i++){for(j=0;j<N;j++){if(i==0)MazeArray[i][j]=1;else if(j==0||j==N-1)MazeArray[i][j]=1;else if(i==M-1)MazeArray[i][j]=1;elseMazeArray[i][j]=array[i-1][j-1];}}cout<<"Initial Maze"<<endl;PrintMaze();}void Maze::PrintMaze(){for(int i=0;i<M;i++){for(int j=0;j<N;j++)cout<<setw(4)<<MazeArray[i][j];cout<<endl;}}Pos Maze::NextPos(Pos &curp){Pos nextp=curp;switch(curp.di){case 1:nextp.x++;break;//rightcase 2:nextp.y++;break;//downcase 3:nextp.x--;break;//leftcase 4:nextp.y--;break;//up}nextp.di=1;return nextp;}bool Maze::FindPath(){LinkStack S;Pos curp=start;do{if(canPass(curp)){Mark(curp);curp.di=1;S.Push(curp);if(isEnd(curp))return true;curp=NextPos(curp);}else{if(!S.StackEmpty()){S.Pop(curp);while(curp.di==4 && !S.StackEmpty()){DeadPos(curp);S.Pop(curp);}if(curp.di<4){curp.di++;S.Push(curp);curp=NextPos(curp);}}}}while(!S.StackEmpty());return false;}void main(){int array[M-2][N-2]={ {0, 1, 0, 0, 0, 0}, {0, 1, 0, 1, 1, 1},{0, 0, 0, 1, 0, 0}, {0, 1, 0, 0, 0, 0},{0, 1, 0, 1, 0, 0}, {0, 1, 0, 1, 1, 0} };Maze M1(array);M1.SetStart();M1.SetEnd();if(M1.FindPath()){cout<<"Find the way."<<endl;M1.PrintMaze();}}个人总结一开始的想法有点偏简单,所以设计出来的算法比较冗长,不过算法在经过多次调试后可以基本实现算法的要求。

最大的不足:之后发现自己的算法实用性太低,迷宫的坐标给定,难以实现互动。

想通过小组讨论改进迷宫的生成部分。

小组讨论后的改进#include<stdio.h>#include<iostream>#include<stdlib.h>#include<time.h>int main(){int m=1,n=1;while((m>0&&m<=20)&&(n>0&&n<=20)){printf("输入迷宫行数m(0<m<=20 否则退出):\n");scanf("%d",&m);printf("输入迷宫列数n(0<n<=20 输入0时退出):\n"); scanf("%d",&n);if(m==0||n==0||m>20||n>20){printf("行列数输入不合要求!");break;}int move[4][2]={{0,1},{1,0},{0,-1},{-1, 0}};typedef struct{int x,y;}position;char maze[22][22];position stack[10000];int x,y,i,ok;int top;position p;srand(time(0));for(x=1;x<=m;x++)for(y=1;y<=m;y++)maze[x][y]=48+rand()%2;maze[1][1]='0';maze[m][n]='0';for(x=0;x<=m+1;x++){maze[x][0]='1';maze[x][n+1]='1';}for(y=0;y<=m+1;y++){maze[0][y]='1';maze[m+1][y]='1';}p.x=1;p.y=1;top=1;stack[top]=p;maze[1][1]='.';do{p=stack[top];ok=0;i=0;while((ok==0)&&(i<4)){x=p.x+move[i][0];y=p.y+move[i][1];if(maze[x][y]=='0'){p.x=x;p.y=y;stack[++top]=p;maze[x][y]='.';ok=1;}i++;}if(i==4){top--;}}while((top>0)&&((p.x!=m)||(p.y!=n)));if(top==0)printf("没有路径\n");elseprintf("有路径\n");for(x=0;x<=m+1;x++){printf("\n");for(y=0;y<=n+1;y++)printf("%c ",maze[x][y]);}printf("\n");}}运行结果总结:讨论后的算法最大的改进是在迷宫的生成部分,针对我提出的问题,我们先提出一种算法:是将迷宫的坐标改为由用户自己输入,后来又提出了一种更好的思想,将这个迷宫生产的部分改为由一个随机函数产生。

相关主题