关于迷宫求解及其最优解的问题
来源:互联网 发布:淘宝联盟导出excel后 编辑:程序博客网 时间:2024/05/14 16:12
关于迷宫问题,求解它的最优解的问题可以使用栈的概念来实现。简单的迷宫如下图
其中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; 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][N];};
三个测试的测试代码及测试结果如下
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是该迷宫的最优路径,即是最短长度。
阅读全文
0 0
- 关于迷宫求解及其最优解的问题
- 数据结构--用栈求解迷宫问题(非最优解)
- 迷宫最优解问题
- 顺序队列求解迷宫(最优解)
- 迷宫求解最优路径
- 迷宫问题的求解
- 简单迷宫最优解问题
- 蚁群算法求解迷宫最优路径问题
- 迷宫问题的递归求解
- 简单迷宫问题的求解
- 一般迷宫问题的求解
- 《最优控制问题的Legendre伪谱法求解及其应用_徐少兵》的仿真结果
- 动态规划求解最大子段问题的最优解
- Maze迷宫问题(最优解)
- 求解木乃伊迷宫问题的源代码
- 基于栈操作的迷宫问题求解
- 利用堆栈实现迷宫问题的求解
- 迷宫问题的C语言求解
- 线性单元
- CentOS常用命令
- 树的遍历
- 3.基础类
- 【Spring】共性问题(九)
- 关于迷宫求解及其最优解的问题
- 继承再剖析
- POJ 3690 Constellations 笔记
- c++重载、覆盖、隐藏,重点隐藏的问题
- Ansible安装
- hibernate 实体的3种状态
- Learning Techniques
- 权值矩阵
- 【Spring】代理模式(十)