迷宫问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法设计与分析课程设计罗密欧与朱丽叶的迷宫问题设计分析测试报告
程序算法设计说明书
一、前言
1、题目:罗密欧与朱丽叶的迷宫问题。
罗密欧与朱丽叶身处一个m×n的迷宫中,如图所示。每一个方格表示迷宫中的一个房间。这m×n个房间中有一些房间是封闭的,不允许任何人进入。在迷宫中任何位置均可沿8 个方向进入未封闭的房间。罗密欧位于迷宫的(p,q)方格中,他必须找出一条通向朱丽叶所在的(r,s)方格的路。在抵达朱丽叶之前,他必须走遍所有未封闭的房间各一次,而且要使到达朱丽叶的转弯次数为最少。每改变一次前进方向算作转弯一次。请设计和实现一个算法帮助罗密欧找出这些道路。
2、程序编制环境相关说明
硬件:装有windows操作系统的计算机
软件:Visual C++ 2008
二、程序主要算法设计分析说明
1、算法设计思路
用回溯法解迷宫问题时,用排列树表示其解空间比较合适。可行性约束函数减去不满足约束条件(x,y,z)已越界的子树。在排列树的第i+1层节点z处用board[z][x][y]记载所在的房间。当bool stepok(int x,int y,int z)返回为false时,以z为根的子树中所有子树都不满足约束条件,因而该子树中的解均为不可行解,故可将该子树剪枝。
算法调用递归方法void backtrack(int dep,int x,int y,int di)实现回溯搜索。void backtrack (int dep,int x,int y,int di)搜索排列树中第dep层子树。数组board[0][x][y]记录排列树中的节点信息。dirs记录当前节点对应的转弯数, best记录最少转弯数。
在算法void backtrack (int dep,int x,int y,int di)中,当i>n时,算法搜索至叶节点,其相应的转弯数dirs。如果dirs>best,则表示当前解优于最优解,此时更新best。当i≤n时,当前扩展节点位于是排列树的第i-1层。此时算法选择下一个要搜索的方向,以深度优先的方式递归地对相应子树进行搜。对于不满足上界约束的节点,则减去相应子树。
算法void backtrack (int dep,int x,int y,int di)动态地生成问题的解空间树。
时间复杂度为整个状态空间,即迷宫大小,O(m*n)
空间复杂度的话深搜和广搜不同.
深搜: 线性时间复杂度,具体看最长的那条路径长度。栈中维持单一路径上的节点
广搜:O(m*n)。队列中保存所有访问过的节点
2、流程图说明
三、程序模块说明
1.总体设计说明
函数之间的关系:
主函数调用search函数,search函数调用comp和save函数完成搜索。如下图main函数
选择输入方式,进入对应函数main1();main2();
调用save函数
调用backtrack函数递归调用backtrack函数
调用stepok函数
输出结果
2.模块说明
2.1函数1:bool stepok(int x,int y,int z)
1)概要说明:判断是(x,y,z)否越界
2)关键数据结构和算法及其分析
bool stepok(int x,int y,int z) //判断是坐标是否越界
{
if(x>0 && x<=n && y>0 && y<=m && board[0][x][y]==0)
returntrue;
else
returnfalse;
}
2.2.函数2:static void save()
1)概要说明:保存转弯最少的路径
2)关键数据结构和算法及其分析
staticvoid save()//保存转弯最少的路径
{
int i,j;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
bestw[l][i][j]=board[0][i][j];
l++;
}
2.3函数3:void backtrack(int dep,int x,int y,int di)
1)概要说明:在当前位置(x,y)按照八个方向搜索,dep用于标记已经走过的房间数,di表示八个方向。
2)关键数据结构和算法及其分析
void backtrack(int dep,int x,int y,int di) // dep用于标记已经走过的房间数di表示八个方向
{
if(dep==m*n-k && x==zx && y==zy && dirs<=best) //找到了朱丽叶
{
if(dirs { best=dirs; number=1; save(); } else { best=dirs; number++; save(); } //是最优路线,道路数目加 return; } if(dep==m*n-k||x==zx&&y==zy||dirs>best)//判断不同情况条件 return; else { for(int i=1;i<=8;i++) { int p = x + dir[i][0]; int q = y + dir[i][1]; int z=0;//计算下一个位置 if(!stepok(p, q,z) || board[0][p][q] != 0) //不在迷宫内或者以前来过或者封闭房间 { continue; } int tmp = board[0][p][q]; board[0][p][q] = dep + 1; //下一个走到的位置