求解迷宫是一件挺简单的事情,对于计算机而已,则需要按算法遍历直到找到解,有路口、有死胡同,所以这个过程和栈的进出过程一样。
若是需要最优解,则需要遍历所有路线找到路径最短的解。
下面是一些对于迷宫求解的算法,希望有用
1.建立一个mazemap。
#include
#include
#include
#include
#pragma warning(disable :4996)
using namespace std;
#define M 10
#define N 10
struct Pos
{
size_t _row;
size_t _col;
};
void GetMaze(int maze[M][N])
{
FILE* out = fopen("maze.txt", "r");
assert(out);
for (size_t i = 0; i < M; i++)
{
for (size_t j = 0; j < N; )
{
char ch = fgetc(out);
if (ch == '0' || ch == '1') //文件内的迷宫0表示可走1表示不能走 其他的是多余的
{
maze[i][j] = ch - '0';
j++;
}
}
}
}
void PrintMaze(int maze[M][N])
{
for (size_t i = 0; i < M; i++)
{
for (size_t j = 0; j < N; j++)
{
printf("%3d",maze[i][j]);
}
cout << endl;
}
}
2.首先可以用循环的方式(这里用上右下左的顺序遍历),直到找到一条出路后结束循环。
若是遇到死胡同则通过出站,回溯的方式退回,来继续寻找解法。
bool Step(int maze[M][N], Pos step) //判断是否可以走
{
if (step._row >= 0 && step._col >= 0
&& step._row < M &&step._col < N
&&maze[step._row][step._col] == 0)
{
return true;
}
return false;
}
bool Path(int maze[M][N], Pos entry) //试探—回溯的方法循环求出迷宫的解
{
stack
path;
path.push(entry);
while (!path.empty())
{
Pos cur = path.top();
maze[cur._row][cur._col] = 2;
Pos next = cur;
if (cur._row == N - 1) //判断此处是否为出口
{
return true;
}
//向上方试探
next._row--;
if (Step(maze, next))
{
path.push(next);
continue;
}
next = cur;
//向右试探
next._col++;
if (Step(maze, next))
{
path.push(next);
continue;
}
next = cur;
//向下试探
next._row++;
if (Step(maze, next))
{
path.push(next);
continue;
}
next = cur;
//向左试探
next._col--;
if (Step(maze, next))
{
path.push(next);
continue;
}
next = cur;
maze[cur._row][cur._col] = 3;
path.pop();
}
return false;
}
这里也可以用递归的方式来遍历出一条路径。
测试:
3.对于最优解便一定要要遍历所有路径,而且以上的走过的路标记为2,回退的路标记为3已经满足不了需求所以,可以用每向前走一步就
+1的方式来进行,而且多一个可以向已经走过但是更大的数字移动。这样不会少遍历而忽略了更小的路径。
然后每次一旦找到一条通路便与上一条最短路径比较,若更短则更新。
bool ShortStep(int maze[M][N],Pos next, Pos cur) //判断可以可以走
{
if (next._row >= 0 && next._col >= 0
&& next._row < M &&next._col < N
&& (maze[next._row][next._col] == 0 || maze[next._row][next._col]>maze[cur._row][cur._col]))
{
return true;
}
return false;
}
void ShortPath(int maze[M][N], Pos cur, stack
& path, stack
& shortpath)
{
path.push(cur);
if (cur._row == N - 1) //判断此处是否为出口
{
if (shortpath.empty()||path.size() < shortpath.size())
{
shortpath = path;
}
}
//向上试探
static Pos next;
next = cur;
next._row --;
if (ShortStep(maze, next, cur))
{
maze[next._row][next._col] = maze[cur._row][cur._col] + 1; //每次试探都在原来基础上+1
ShortPath(maze, next, path, shortpath);
}
//向右试探
next = cur;
next._col ++;
if (ShortStep(maze, next, cur))
{
maze[next._row][next._col] = maze[cur._row][cur._col] + 1;
ShortPath(maze, next, path, shortpath);
}
//向下试探
next = cur;
next._row ++;
if (ShortStep(maze, next, cur))
{
maze[next._row][next._col] = maze[cur._row][cur._col] + 1;
ShortPath(maze, next, path, shortpath);
}
//向左试探
next = cur;
next._col --;
if (ShortStep(maze, next, cur))
{
maze[next._row][next._col] = maze[cur._row][cur._col] + 1;
ShortPath(maze, next, path, shortpath);
}
path.pop();
}
测试: