如何在迷宫中找到最快的路线(C)
迷宫被定义为一个正方形矩阵。 例如:如何在迷宫中找到最快的路线(C),c,recursion,maze,C,Recursion,Maze,迷宫被定义为一个正方形矩阵。 例如: int maze[N][N] = { { 1, 1, 1, 1, 1, 1, 1 }, { 0, 1, 0, 1, 0, 0, 1 }, { 0, 1, 0, 1, 1, 1, 1 }, { 0, 1, 0, 0, 0, 1, 1 }, { 0, 1, 1, 1, 0, 1, 1 }, { 0, 0, 1, 0, 1, 1, 1 }, { 1, 1, 1, 1, 0, 1, 1 } }; 你只能在有1的地
int maze[N][N] =
{ { 1, 1, 1, 1, 1, 1, 1 },
{ 0, 1, 0, 1, 0, 0, 1 },
{ 0, 1, 0, 1, 1, 1, 1 },
{ 0, 1, 0, 0, 0, 1, 1 },
{ 0, 1, 1, 1, 0, 1, 1 },
{ 0, 0, 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 0, 1, 1 } };
你只能在有1的地方走。
你可以向下、向上、向左、向右走一步。
从左上角开始,到右下角结束
输出应该是完成任何迷宫的最小步骤。
我们可以假设至少有一种方法可以完成迷宫。
我已经编辑了代码,我想我已经涵盖了所有内容。。但很明显我遗漏了什么。
谢谢你的帮助
int path_help(int maze[][N], int row, int col, int count)
{
int copy1[N][N], copy2[N][N], copy3[N][N];
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
copy1[i][j] = maze[i][j];
copy2[i][j] = maze[i][j];
copy3[i][j] = maze[i][j];
}
}
int a, b, c, d;
if (col == 0 || row == 0)
{
if (row == N - 1)
{
if (maze[row][col + 1] == 1)
{
maze[row][col] = 0;
return path_help(maze, row, col + 1, count + 1);
}
else return N*N;
}
if (col == N - 1)
{
if (maze[row + 1][col] == 1)
{
maze[row][col] = 0;
return path_help(maze, row + 1, col, count + 1);
}
else return N*N;
}
if (maze[row][col + 1] == 1 && maze[row + 1][col] == 1)
{
maze[row][col] = 0;
copy1[row][col] = 0;
return min(path_help(copy1, row, col + 1, count + 1),path_help(maze, row + 1, col, count + 1));
}
if (maze[row][col + 1] == 0 && maze[row + 1][col] == 1)
{
maze[row][col] = 0;
return path_help(maze, row + 1, col, count + 1);
}
if (maze[row + 1][col] == 0 && maze[row][col + 1] == 1)
{
maze[row][col] = 0;
return path_help(maze, row, col + 1, count + 1);
}
else return N*N;
}
if (col == N - 1 || row == N - 1)
{
if (col == N - 1 && row == N - 1) return count;
if (row == N - 1)
{
if (maze[row - 1][col] == 1 && maze[row][col + 1] == 1)
{
maze[row][col] = 0;
copy1[row][col] = 0;
return min(path_help(copy1, row, col + 1, count + 1), path_help(maze, row - 1, col, count + 1));
}
if (maze[row - 1][col] == 0 && maze[row][col + 1] == 1)
{
maze[row][col] = 0;
return path_help(maze, row, col + 1, count + 1);
}
if (maze[row][col + 1] == 0 && maze[row - 1][col] == 1)
{
maze[row][col] = 0;
return path_help(maze, row - 1, col, count + 1);
}
else return N*N;
}
if (col == N - 1)
{
if (maze[row + 1][col] == 1 && maze[row][col - 1] == 1)
{
maze[row][col] = 0;
copy1[row][col] = 0;
return min(path_help(copy1, row, col - 1, count + 1), path_help(maze, row + 1, col, count + 1));
}
if (maze[row + 1][col] == 0 && maze[row][col - 1] == 1)
{
maze[row][col] = 0;
return path_help(maze, row, col - 1, count + 1);
}
if (maze[row][col - 1] == 0 && maze[row + 1][col] == 1)
{
maze[row][col] = 0;
return path_help(maze, row + 1, col, count + 1);
}
else return N*N;
}
}
if (maze[row + 1][col] == 1)
{
maze[row][col] = 0;
a = path_help(maze, row + 1, col, count + 1);
}
else a = N*N;
if (maze[row - 1][col] == 1)
{
copy1[row][col] = 0;
b = path_help(copy1, row - 1, col, count + 1);
}
else b = N*N;
if (maze[row][col + 1] == 1)
{
copy2[row][col] = 0;
c = path_help(copy2, row, col + 1, count + 1);
}
else c = N*N;
if (maze[row][col - 1] == 1)
{
copy3[row][col] = 0;
d = path_help(copy3, row, col - 1, count + 1);
}
else d = N*N;
return min(min(a, b),min( c, d));
int-path\u帮助(int-maze[][N],int-row,int-col,int-count)
{
int copy1[N][N]、copy2[N][N]、copy3[N][N];
对于(int i=0;i
}从根本上说,这是一个搜索问题。有很多关于如何解决问题的很好的文章,所以我将讨论一些你需要考虑的细节。p> 因为您需要指定最短路径,而不仅仅是一条“非常好”的路径,所以需要检查每一条可能的路径。深度优先搜索是我的建议
最明显的是,这是没有重用的搜索。最短路径将不包含任何循环,也不包含光标将返回到其已到达的位置的任何情况。这使搜索区域保持合理。如果运行时不是问题,您可以编写一个函数来尝试每个可能的路由,并返回最小值
int path_helper(int maze[][N],int height, int width, int row, int col){
if(row==height-1 && col == width-1) return 0;
if(maze[row][col]==0) return height*width;
if(col<0 || row<0 || row>=height || col>=width) return height*width;
maze[row][col]=0;
int maze2[7][7]={{0}};
for(int i = 0; i < height; i++){
for(int j = 0; j < width; j++)
maze2[j][i]=maze[j][i];
}
return min(min(path_helper(maze2,height,width,row+1,col),
path_helper(maze2,height,width,row-1,col)), min(path_helper(maze2,height,width,row,col+1),path_helper(maze2,height,width,row,col-1)))+1;
}
int-path\u助手(int-maze[][N],int-height,int-width,int-row,int-col){
if(row==height-1&&col==width-1)返回0;
如果(迷宫[行][列]==0)返回高度*宽度;
如果(列=宽度)返回高度*宽度;
迷宫[行][列]=0;
int maze2[7][7]={{0};
对于(int i=0;i
这很难看,但它应该起作用因为@Jackson链接的问题没有解决方案,这里有一个改进的算法,适用于这个迷宫问题。我将迷宫值
0
视为无法通过,将1
视为算法的距离
看起来好像neigh()
函数应该是递归的,但它不是,它只是以同样的方式检查4个邻居。请注意,并不是所有的路径都遵循:对于一个可能是O(不!)的大型迷宫。另外,搜索并不是指向终点:终点是遇到的,算法的这些特性赋予了它的美感
#include <stdio.h>
#include <stdio.h>
#include <limits.h>
#define MSIZE 7 // matrix/maze dims
enum ntype { virgin, listed, visited }; // for status field
typedef struct {
int x; // grid position of node
int y; // grid position of node
int value; // 0 or 1 as defined in maze[][]
int dist; // distance from start node
int status; // enum as above
} node_t;
int maze[MSIZE][MSIZE] = // maze definition
{ { 1, 1, 1, 1, 1, 1, 1 },
{ 0, 1, 0, 1, 0, 0, 1 },
{ 0, 1, 0, 1, 1, 1, 1 },
{ 0, 1, 0, 0, 0, 1, 1 },
{ 0, 1, 1, 1, 0, 1, 1 },
{ 0, 0, 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 0, 1, 1 } };
node_t node [MSIZE][MSIZE]; // working array
node_t *list[MSIZE*MSIZE]; // array of current node pointers
int listlen; // num elements in list[]
void neigh(node_t *cptr, int dx, int dy)
// examine one neighbour of node cptr, offset by dx,dy
{
node_t *nptr; // pointer to neighbour
int dist; // accumulated distance from start
int x = cptr->x + dx; // work out neighbour coords
int y = cptr->y + dy; // work out neighbour coords
if (x < 0 || x >= MSIZE || y < 0 || y >= MSIZE)
return; // failed edge test
nptr = &node[y][x]; // point to neighbour
if (nptr->value == 0) // no-go node
return;
if (nptr->status == visited) // do no re-visit
return;
dist = cptr->dist + nptr->value; // accumulate distance from start
if (dist < nptr->dist) // if it's less than what was known...
nptr->dist = dist; // ...update with the new distance
if (nptr->status == virgin) { // if it's never been seen...
list[listlen++] = nptr; // ... neighbour to list
nptr->status = listed; // and set its status
}
}
int main(void)
{
int i, j, smallest, smallind;
node_t *cptr, *eptr;
// init the struct array
for (j=0; j<MSIZE; j++) {
for (i=0; i<MSIZE; i++) {
cptr = &node[j][i]; // pointer to the array element
cptr->value = maze[j][i]; // the maze definition
cptr->x = i; // self's position
cptr->y = j; // self's position
cptr->dist = INT_MAX; // distance from start (unknown)
cptr->status = virgin; // never examined
}
}
eptr = &node[MSIZE-1][MSIZE-1]; // pointer to end node
cptr = &node[0][0]; // pointer to start node
cptr->dist = 0; // distance of start node from itself!
// main loop
while (cptr != eptr) { // until we reach the target node
cptr->status = visited; // we've been here now
neigh(cptr, 0, -1); // examine node above
neigh(cptr, -1, 0); // examine node on left
neigh(cptr, 1, 0); // examine node on right
neigh(cptr, 0, 1); // examine node below
// find smallest distance of nodes in list[] (won't include virgins)
smallest = INT_MAX;
smallind = -1; // set invalid marker index
for (i=0; i<listlen; i++) {
if (smallest > list[i]->dist) { // compare distance with smallest
smallest = list[i]->dist; // remembers the smallest
smallind = i; // remembers the list index of smallest
}
}
// take smallest for next time and remove from list
if(smallind < 0) { // -1 was the "marker"
printf("No route found\n");
return 1;
}
cptr = list[smallind]; // smallest becomes current node
if (listlen) // replace in list with last element...
list[smallind] = list[--listlen];// ... and reduce list length
} // now examine this node
printf("Distance = %d\n", eptr->dist); // show the distance of the end node
return 0;
}
编辑链接中描述了算法本身,如果算法中断,肯定会有其他解释可用。我哈
Distance = 12