关于迷宫求解及其最优解的问题
2017-10-08 11:39
369 查看
关于迷宫问题,求解它的最优解的问题可以使用栈的概念来实现。简单的迷宫如下图
![](https://img-blog.csdn.net/20171008113853017?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHZ5aWJpbjg5MA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
其中0表示可以走,1表示不能走,显然可见,若是以(3,1)点为入口,则有两个出口分别是(10,3)和(10, 8)。而两个出口的路径长度是不同的。这就产生了迷宫最优解的问题。
![](https://img-blog.csdn.net/20171008121928143?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHZ5aWJpbjg5MA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
下面附上代码,我们寻找下一个位置是否可走的顺序是顺时针顺序,即上右下左。
三个测试的测试代码及测试结果如下
递归走
![](https://img-blog.csdn.net/20171008122524601?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHZ5aWJpbjg5MA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
非递归走,我们为了突出效果,把(10,8)的出口给封掉,变成不可走
![](https://img-blog.csdn.net/20171008122828969?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHZ5aWJpbjg5MA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
可以看到,以上两种因为查找下一位置的顺序的原因,只找到了一个出口,那么要找出最优的路径,就必须把所有的路径长度求出来进行比较,用3表示满足不了需求,我们可用没走一步就+1的方法来表示。
![](https://img-blog.csdn.net/20171008123108523?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHZ5aWJpbjg5MA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
两条路径的长度分别是9和14,显然9是该迷宫的最优路径,即是最短长度。
其中0表示可以走,1表示不能走,显然可见,若是以(3,1)点为入口,则有两个出口分别是(10,3)和(10, 8)。而两个出口的路径长度是不同的。这就产生了迷宫最优解的问题。
下面附上代码,我们寻找下一个位置是否可走的顺序是顺时针顺序,即上右下左。
#pragma once #include<iostream> using namespace std; //#define _CRT_SECURE_NO_WARNINGS #pragma warning(disable:4996) #include<assert.h> #include<stdio.h> #include<stack> struct Pos { int _row; int _col; }; template<size_t M,size_t N> class Maze { public: Maze() { FILE* fout = fopen("MazeMap.txt", "r"); assert(fout); for (size_t i = 0; i < M; ++i) { for (size_t j = 0; j < N;) { char ch = fgetc(fout); if (ch == '1' || ch == '0') //构建一个以文字内数字为元素的二维数组,1表示不可走,0表示可走 { _maze[i][j] = ch - '0'; ++j; } } } } bool CheckAccess(Pos pos)//检查下一个位置是否可以走 { if ((pos._row<M)&&(pos._col<N)&&(_maze[pos._row][pos._col] == 0)) { return true; } return false; } bool GetMazePathR(Pos cur)//递归走 { _maze[cur._row][cur._col] = 2;//用2表示走过的位置来记录 //找到出口 if (cur._row == M - 1) { return true; } //探测 Pos next = cur; //上 next._row -= 1; if (CheckAccess(next)) { if (GetMazePathR(next)) return true; } //右 next = cur; next._col += 1; if (CheckAccess(next)) { if (GetMazePathR(next)) return true; } //下 next = cur; next._row += 1; if (CheckAccess(next)) { if (GetMazePathR(next)) return true; } //左 next = cur; next._col -= 1; if (CheckAccess(next)) { if (GetMazePathR(next)) return true; } return false; } bool GetMazePathNonR(Pos entry)//非递归走,用回溯的方法 { stack<Pos> path; path.push(entry);//先将入口push到栈中 while (!path.empty()) { Pos cur = path.top(); _maze[cur._row][cur._col] = 2;//用2表示走过的位置来记录 Pos next = cur; if (cur._row == M-1) { return true; } //向上探测 --next._row; if (CheckAccess(next)) { path.push(next); continue; } next = cur;//如果不能走,让next回到初始的cur的位置 //向右探测 ++next._col; if (CheckAccess(next)) { path.push(next); continue; } next = cur; //向下探测 ++next._row; if (CheckAccess(next)) { path.push(next); continue; } next = cur; //向左探测 --next._col; if (CheckAccess(next)) { path.push(next); continue; } next = cur; _maze[cur._row][cur._col] = 3; //如果一个if条件都没有进,那么该位置是死胡同,不能走,用3来表示 path.pop();//将该位置pop出栈 } return false; } bool CheckAccess(Pos cur,Pos next) //与上一个CheckAccess函数形成重载 { if ((next._row>=M) || (next._col>=N) ) { return false; } if ((_maze[next._row][next._col] == 0) || (_maze[next._row][next._col]> (_maze[cur._row][cur._col] + 1))) { return true; } return false; } void GetMazeShortPathR(Pos cur, stack<Pos>& paths, stack<Pos>& shortpaths) //求解出口的最短路径 { paths.push(cur); //找到出口 if (cur._row == M - 1) { if (shortpaths.empty()||(shortpaths.size()>paths.size())) { shortpaths = paths; } return; } //探测 Pos next = cur; //上 next._row -= 1; if (CheckAccess(cur,next)) { _maze[next._row][next._col] = _maze[cur._row][cur._col] + 1; GetMazeShortPathR(next, paths, shortpaths); } //右 next = cur baea ; next._col += 1; if (CheckAccess(cur, next)) { _maze[next._row][next._col] = _maze[cur._row][cur._col] + 1; GetMazeShortPathR(next, paths, shortpaths); } //下 next = cur; next._row += 1; if (CheckAccess(cur,next)) { _maze[next._row][next._col] = _maze[cur._row][cur._col] + 1; GetMazeShortPathR(next, paths, shortpaths); } //左 next = cur; next._col -= 1; if (CheckAccess(cur,next)) { _maze[next._row][next._col] = _maze[cur._row][cur._col] + 1; GetMazeShortPathR(next, paths, shortpaths); } paths.pop(); } void Print() { for (size_t i = 0; i < M; ++i) { for (size_t j = 0; j < N;++j) { cout << _maze[i][j] << " "; } cout << endl; } cout << endl; } protected: int _maze[M] ; };
三个测试的测试代码及测试结果如下
void TestMaze() { Maze<10, 10> m; m.Print(); Pos entry = {2,0}; stack<Pos> paths, shortpaths; //cout << "找到出口?" << m.GetMazePathR(entry) << endl; //cout << "找到出口?" << m.GetMazePathNonR(entry) << endl; m.GetMazeShortPathR(entry, paths, shortpaths); m.Print(); }
递归走
非递归走,我们为了突出效果,把(10,8)的出口给封掉,变成不可走
可以看到,以上两种因为查找下一位置的顺序的原因,只找到了一个出口,那么要找出最优的路径,就必须把所有的路径长度求出来进行比较,用3表示满足不了需求,我们可用没走一步就+1的方法来表示。
两条路径的长度分别是9和14,显然9是该迷宫的最优路径,即是最短长度。
相关文章推荐
- 数据结构--用栈求解迷宫问题(非最优解)
- 关于栈与递归求解迷宫与迷宫最短路径问题
- 关于迷宫问题的dfs与bfs两中求解方式
- Java求解迷宫问题:栈与回溯算法
- 我学员的一个问题及其我对之的解答,关于lr返回值问题
- 关于n皇后问题的递归求解,有详细的步骤说明。
- 利用栈求解迷宫问题
- 关于递推算法求解约瑟夫环问题P(n,m,k,s)
- C语言及程序设计进阶例程-25 排序问题及其求解
- 迷宫最优解问题
- 关于蛇形填数问题求解
- 简单迷宫最优解问题
- 关于比赛安排的求解问题
- ~~~关于ExpandableListAdapter的一个比较二的问题,求解啊~~~
- 《最优控制问题的Legendre伪谱法求解及其应用_徐少兵》的仿真结果
- 回溯算法求解迷宫问题
- Maze迷宫问题(求最优解)
- 迷宫问题用‘图’求解
- 求解 关于 套汇问题 要求 使用 C++
- 我学员的一个问题及其我对之的解答,关于lr返回值问题