收藏 分享(赏)

算法分析与设计 查找迷宫的最短路径(深度算法).docx

上传人:dreamzhangning 文档编号:2734324 上传时间:2018-09-26 格式:DOCX 页数:11 大小:372.70KB
下载 相关 举报
算法分析与设计 查找迷宫的最短路径(深度算法).docx_第1页
第1页 / 共11页
算法分析与设计 查找迷宫的最短路径(深度算法).docx_第2页
第2页 / 共11页
算法分析与设计 查找迷宫的最短路径(深度算法).docx_第3页
第3页 / 共11页
算法分析与设计 查找迷宫的最短路径(深度算法).docx_第4页
第4页 / 共11页
算法分析与设计 查找迷宫的最短路径(深度算法).docx_第5页
第5页 / 共11页
点击查看更多>>
资源描述

1、算法分析与设计查找迷宫的最短路径(深度算法)计算机科学与技术 12 级16 班 2012/12/16 1 / 11【摘要】:迷宫求解是一个古老的游戏,要在迷宫中找到出口,需要经过一连串的错误尝试才能找到正确的路径,有的时候甚至找不到路径。类似于给定一个 m*n 的矩形网格,设其左上角为起点 S。一辆汽车从起点出发驶向右下角终点 T。在若干网格处设置了障碍,表示该网格不可到达。设计一个算法,求汽车从起点 S 出发到达终点 T 的一条路线。用计算机求解这个问题时,我们通常采用的是回溯方法,即从入口出发,顺某方向向前探索,若能走通,则继续往前走;否则沿原路退回。换一个方向再继续探索,直至所有可能的通

2、路都探索到为止。为了保证在任何位置上都能沿原路退回,显然需要用一个后进先出的结构来保存从入口到当前位置的路径。因此,在求迷宫通路的算法中应用“栈”也就是自然而然的事。当然还有其他的方法来解决,例如顺序表,深度优先遍历,广度优先遍历等。【关键词】: 最短路径; 时间复杂度; 深度优先搜索【Summary】Maze solving is an ancient game , you want to find the exit in the maze , need to go through a series of trial and error to find the right path , an

3、d sometimes not even find the path . A m * n rectangular grid , similar to a given set its upper-left corner as the starting point S . A car from the starting point towards the bottom right corner of the end of T . Set up barriers at certain grid , indicates that the grid is unreachable . Design an

4、algorithm , find the car starting to reach the end point T, route from the starting point S . Use the computer to solve this problem , we usually use the backtracking method , that is, starting from the entrance , Shun forward to explore a direction , if we go through , and continue to move forward

5、; otherwise return along the same route . Continue to explore another direction , until all possible paths to explore to far . In order to ensure that in any position along the same route back , it is clear that the need to use a LIFO structure to save the path from the entrance to the current posit

6、ion . Therefore , in seeking labyrinth path algorithm application “stack“ is the natural thing to do . Of course , there are other ways to solve , for example, the sequence table , depth-first traversal , breadth -first traversal .【Key phrase】Shortest path ; time complexity ; deep-first search2 / 11

7、目录摘要 1关键字 1Summary1一、问题描述 3二、算法分析 3三、设计方案 .31 总体方案 32 主要设计思路 .3四、时间复杂度 6五、总结 6六、参考文献 7七、附录 73 / 11一、 问题描述迷宫最短路径( the shortest path of maze) 问题是一个典型的搜索、遍历问题, 其程序设计想在人工智能设计、机器人设计等事务中均有应用。如图 所示, 一个 NM 的大方块迷宫 , 带斜线的单元格表示墙壁( 障碍) , 空白的单元格表示通道。迷宫问题可以表述为:寻找从某一个给定的起始单元格( 迷宫入口) 出发, 经由行相邻或列相邻的通道单元格, 最终可以到达目标单元

8、格( 迷宫出口 ) , 所走过的单元格序列。行进中 , 只能沿上下左右四个方向前进。而迷宫最短路径问题就是找出从迷宫入口到出口所经过单元格个数最少的路径。二、 算法分析从入口出发, 顺着某一方向向前探索, 若能走通, 则继续往前走; 否则沿原路退回( 回溯) , 换一个方向再继续探索, 直至所有可能的通路都探索到为止。如果恰好某一步探索到出口, 则就找到了从入口到出口的路径。为了保证在任何位置上都能沿原路退回, 防止死循环, 需要使用堆栈来保存大量记录。而要求解迷宫最短路径, 则必须用深度优先搜索出所有到达出口的路径, 通过比较得到最短距离的路径, 这样也必然要求增加数据空间来保存搜索过程中当

9、前最短路径, 增加了空间复杂度。三、 设计方案1 总体方案走迷宫问题的走迷宫的过程可以模拟为一个搜索的过程:每到一处,总让它按东、南、西、北、4 个方向顺序试探下一个位置;如果某方向可以通过,并且不曾到达,则前进一步,在新位置上继续进行搜索;如果 4 个方向都走不通或曾经到达过,则退回一步,在原来的位置上继续试探下一位置。每前进或后退一步,都要进行判断:若前进到了出口处,则说明找到了一条通路;若退回到了入口处,则说明不存在通路。2 主要设计思路用一个字符类型的二维数组表示迷宫,输入值的范围是 0,1,其中 0 表示路径,1 为非路径(即障碍),输入的矩阵大小和矩阵的内容是靠手动输入。设计一个模

10、拟走迷宫的算法,为其寻找一条从入口点到出口点的通路。解决迷宫问题,面对的第一个问题是迷宫的表示方法。假定用 n*m 矩阵来描述迷宫。左上角为入口,右下角为出口。n 和 m 分别表示迷宫的行数和列数。矩阵中,0 表示可通行的路径,1 代表障碍。如图 1-1 表示 4*6 的迷宫矩阵表示。0 1 1 0 0 00 0 0 1 0 00 0 0 0 0 00 1 1 0 0 0图 1-1 迷宫问题的矩阵表示如果现在的位置(i,j),则下一步有:上、下、左、右四种走法,如图 1-2 表示。4 / 11(i-1,j)(i,j-1) (i,j) (i,j+1)(i+1,j)图 1-2 四种可能的移动方向迷

11、宫内部的位置有四种移动的位置:上、下、左、右。而迷宫的边界位置有两种或三种可能的移动。为避免在处理内部和边界位置是存在差异,可在迷宫的周围增加一圈障碍物,如图 1-3表示。1 1 1 1 1 1 1 11 0 1 1 0 0 0 11 0 0 0 1 0 0 11 0 0 0 0 0 0 11 0 1 1 0 0 0 11 1 1 1 1 1 1 1图 1-3 为迷宫增加一圈障碍物增加一圈障碍物之后,原迷宫中的每个位置都可以有四种移动方向。而且可以使程序不必去处理边界条件,从而大大简化代码的设计。这种简化是以稍稍增加数组 amze 的空间为代价的。分别用 x 和 y 来指定每个迷宫位置的行坐标

12、和列坐标。可以定义一个类 class T 来表示迷宫的位置。class T /定义描述迷宫中当前位置的结构类型public:int x; /x 代表当前位置的行坐标int y; /y 代表当前位置的列坐标int dir; /0:无效,1: 右,2:下,3:左,4:上;当输入一个二维数组时,每次输入的元素都存放在一个栈里面。所以定义一个栈 Stack 用于存放二维数组元素。这里用到栈,栈是限定尽在表位进行插入和删除的线性表。对于栈来说,允许进行插入和删除的一段,称为栈顶;不允许插入和删除的另一端,则成为栈底。在这个问题中主要运用了栈的各种基本操作,例如构造空栈,判断栈是否为空,入栈操作,出栈操作

13、等等。这里是栈的一个重要应用,就是实现递归。class Stack public:Stack(); /构造函数,置空栈Stack(); /析构函数void Push(T e); /把元素 data 压入栈中T Pop(); /使栈顶元素出栈T GetPop(); /取出栈顶元素void Clear(); /把栈清空bool empty(); /判断栈是否为空,如果为空则返回 1,否则返回 0private:LinkNode *top; ; /指向第一个结点的栈顶指针5 / 11调试结果如图 1-4:图 1-4 迷宫和矩阵的建立如果位置(i,j)的下一步的四个方向都是可以走的,假设出发的先后顺序

14、是向上 .向下.向左.向右。每个结点都是按照先后顺序来决定下一个结点的方向。一旦做出了决定,就需要知道下一个位置的坐标。可通过保留一个如图 1-5 所示的偏移量表来计算这些坐标。可以把向右.向左.向下.向上移动分别编号为 0.1.2.3。在图 1-3 中,movei.x 和 movei.y 分别给出了从当前位置沿方向移动到下一个相连位置时,x 和 y 坐标的增量。方向索引值(dir)movedir.x movedir.x 方向0 0 1 右1 1 0 下2 0 -1 左3 -1 0 上图 1-5 偏移量表因此假设现在的位置是(2,3) ,则其右边相连位置坐标的行坐标为 2+move0.x=2,

15、列坐标为3+move0.y=4.定义一个主函数 int main(),用于调用其他函数实现函数的嵌套调用,实现整个程序。这里运用的二维指针我是参考书上的。int main()int m=0,n=0; /定义迷宫的长和宽int *maze; /定义二维指针存取迷宫maze=GetMaze(m,n); /调用 GetMaze(int class T /定义描述迷宫中当前位置的结构类型public:int x; /x 代表当前位置的行坐标int y; /y 代表当前位置的列坐标int dir; /0:无效,1:右,2: 下,3:左,4:上;class LinkNode /链表结点friend cla

16、ss Stack;public:T data;LinkNode *next;class Stack public:Stack(); /构造函数,置空栈Stack(); /析构函数void Push(T e); /把元素 data 压入栈中T Pop(); /使栈顶元素出栈T GetPop(); /取出栈顶元素bool empty(); /判断栈是否为空,如果为空则返回 1,否则返回 0private:LinkNode *top; /指向第一个结点的栈顶指针;Stack:Stack() /构造函数,置空栈top=NULL;Stack:Stack() /析构函数void Stack:Push(T

17、e) /把元素 x 压入栈中LinkNode *P;P=new LinkNode;P-data=e;8 / 11P-next=top;top=P;T Stack:Pop() /使栈顶元素出栈T Temp;LinkNode *P;P=top;top=top-next;Temp=P-data;delete P;return Temp;T Stack:GetPop() /取出栈顶元素return top-data;bool Stack:empty() /判断栈是否为空,如果为空则返回 1,否则返回 0if(top=NULL) return 1;else return 0;int move42=0,1

18、,1,0,0,-1,-1,0; /定义当前位置移动的 4 个方向bool Mazepath(int *maze,int m,int n); /寻找迷宫 maze 中从(0,0)到(m,n)的路径/到则返回 true,否则返回 falsevoid PrintPath(Stack p); /输出迷宫的路径int* GetMaze(int /获取迷宫/返回存取迷宫的二维指针int main()int m=0,n=0; /定义迷宫的长和宽int *maze; maze=GetMaze(m,n); /调用 GetMaze(int /输入迷宫的长和宽coutmazeij;for(i=0;idata=p.P

19、op(); /取栈 p 的顶点元素,即第一个位置t.Push(temp-data); /第一个位置入栈 tdelete temp; /释放空间while(!p.empty() /栈 p 非空,则反复转移temp=new LinkNode;temp-data=p.Pop(); /获取下一个位置/得到行走方向a=t.GetPop().x-temp-data.x; /行坐标方向b=t.GetPop().y-temp-data.y; /列坐标方向if(a=1) temp-data.dir=1; /方向向下,用 1 表示else if(b=1) temp-data.dir=2; /方向向右,用 2 表示

20、else if(a=-1) temp-data.dir=3; /方向向上,用 3 表示 else if(b=-1) temp-data.dir=4; /方向向左,用 4 表示t.Push(temp-data); /把新位置入栈delete temp;/输出路径,包括行坐标,列坐标,下一个位置方向while(!t.empty() /栈非空,继续输出data=t.Pop();cout(data.x,data.y“,“; /输出行坐标,列坐标switch(data.dir) /输出相应的方向 case 1:cout“下)n“;break;case 2:cout“右)n“;break;case 3:cout“上)n“;break;case 4:cout“左)n“;break;case 0:cout“)n“;break;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 大学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报