回溯法解迷宫问题

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

算法分析与设计论文论文题目:回溯法解迷宫问题

作者姓名陈相艺

任课教师王松

学院班级计算机学院计自1101班

学号201126100404

提交日期2013年6月10日

回溯法解迷宫问题

陈相艺

(计算机+自动化1101 201126100404)

摘要:迷宫的存储结构以二维数组来存储,用0,1表示通或不通。表面上似乎迷宫问题是一种特殊问题的解决方法,其实迷宫问题是一种特殊形式图的问题,因此,迷宫总量可转化为图的问题来解决。设计一个计算机程序对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论.本文采用回溯法求解迷宫路径,算法用到数据结构中的栈。

关键词:迷宫;二位数组;回溯法;栈;矩阵。

1.前言

迷宫实验是取自心理学的一个古典实验.在该实验中,把一只老鼠从一个无顶大盒子放入,在盒中设立了许多墙,对行进方向形成了多处阻挡.盒子仅有一个出口处放置一快奶酪,吸引老鼠在迷宫中寻找道路以到达出口.对同一老鼠重复进行上述实验,一直到老鼠从入口到出口,而不走错一步.老鼠经多次试验终于得到它学习走通迷宫的线路.设计一个计算机程序对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论.

回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

2.迷宫问题的算法思想及研究

迷宫问题中,在寻找路径时,采用的方法通常是:从入口出发,沿某一方向向前试探,若能走通,则继续向前进;如果走不通,则要沿原路返回,换一个方向再继续试探,直到所有可能的能跟都试探完成为止。为了保证在任何位置上都能沿原路返回(回溯),要建立一个后进先出的栈来保存从入口到当前位置的路径。而且在求解迷宫路径中,所求得的路径必须是简单路径。即在求得的路径上不能有重复的同一块通道。

为了表示迷宫,设置一个数组,其中每个元素表示一个方块的状态,为0时表示对应方块是通道,为1时表示对应方块为墙,数组如下所示:

int mg[10][10] = {

{1,1,1,1,1,1,1,1,1,1},

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

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

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

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

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

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

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

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

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

(可根据自己喜好,改变迷宫的大小和通道安排。)

对于迷宫中每个方块,都有上下左右四个方块相邻,第i行第j列的当前方块的位置为(i,j),

规定上方方块为方位0,按顺时针方向递增编号。假设从方位0到方位3的方向查找下一个可走方块。为便于回溯,对于可走的方块都要进栈,并试探它的下一个可走方位,将这个可走的方位保存到栈中,栈定义如下:

class St

{ public:

inti;

int j;

int di;

} St[MaxSize];

求解路径过程为:先将入口进栈(初始方位设置为-1),在栈不为空时循环:取栈顶方块(不退栈),若是出口,则输出栈中方块即为路径。否则,找下一个可走的相邻方块,若不存在这样的方块,则退栈。若存在,即将其方位保存到栈顶元素中,并将这个可走相邻方块进栈(初始方位设置为-1)。为保证试探可走相邻方块不是已走路径上的方块,如(i,j)已经进栈,在试探(i+1,j)的下一可走方块时,又试探到(i,j),这样会引起死循环,为此,在一个方块进栈后,将对应的mg数组元素值改为-1(变为不可走),当退栈时(没有可走的相邻方块),将其恢复为0.接上上面介绍的迷宫数组和栈,总的算法如下:

#include

#include

#include

using namespace std;

#define MaxSize 100

int mg[10][10] = { //定义一个迷宫,0表示通道,1表示墙

{1,1,1,1,1,1,1,1,1,1},

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

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

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

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

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

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

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

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

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

class St //定义一个栈,保存路径

{ public:

inti; //当前方块的行号

int j; //当前广场的列号

int di; //di是下一可走方位的方位号

} St[MaxSize]; //定义栈

int top = -1; //初始化栈指针

void MgPath(int xi, intyi, intxe, int ye) //路径为从(xi,yi)到(xe,ye)

{

inti, j, di, find, k;

top++; //初始方块进栈

St[top].i = xi;St[top].j = yi;St[top].di = -1;

mg[xi][yi] = -1;

while(top>-1) //栈不为空时循环

{

i = St[top].i;j = St[top].j;di = St[top].di;

if(i==xe&& j==ye) //找到了出口,输出路径

{

cout<< "迷宫路径如下:/n";

for(k=0; k<=top; k++)

{

cout<< "/t(" << St[k].i<< "," << St[k].j << ")";

if((k+1)%5==0) cout<

cout<

return;

}

find = 0;

while(di<4 && find==0) //找下一个可走方块

{

di++;

switch(di)

{

case 0:i = St[top].i-1; j = St[top].j; break;

case 1:i = St[top].i; j = St[top].j+1; break;

case 2:i = St[top].i+1; j = St[top].j; break;

case 3:i = St[top].i; j = St[top].j-1; break;

}

if(mg[i][j]==0) find = 1; //找到通路

}

if(find==1) //找到了下一个可走方块

{

St[top].di = di; //修改原栈顶元素的di值

top++; //下一个可走方块进栈St[top].i = i; St[top].j = j; St[top].di = -1;

mg[i][j] = -1; //避免重复走到这个方块}

else //没有路可走,则退栈

{

mg[St[top].i][St[top].j] = 0; //让该位置变成其它路径可走方块

相关文档
最新文档