追踪迷宫,从源头到达目标

Trace the maze to reach from source to goal

本文关键字:目标 源头 迷宫 追踪      更新时间:2023-10-16

我正在尝试实现一个问题的解决方案,其中我需要在迷宫中递归地找到从源到目标的路径。

假设这是迷宫: S X X X X X . . . . . X X . X X X X X . X X X X . . . X . G X X . . . X 其中

X阻塞路径

.-开放路径

S-启动

G-目标

我已经编写了以下代码来实现该解决方案,但它给了我一个分段错误。如果有人能告诉我哪里做错了,我会很高兴。

我的解决方案是

#include<iostream>
using namespace std;
void printGrid(char grid[6][6])
{
    for(int i=0;i<6;i++)
    {
        for(int j=0;j<6;j++)
        {
            cout<<grid[i][j]<<" ";
        }
        cout<<"n";
    }
}
bool isValidPoint(char grid[6][6],int x,int y)
{   
    if(x<0 || x>5 || y<0 || y>5)
    {
        return false;
    }
    if(grid[x][y]=='X')
    {
        return false;
    }
    return true;
}
bool traceMaze(char grid[6][6],int x,int y)
{
    if(!isValidPoint(grid,x,y))
    {
        return false;
    }
    if(grid[x][y]=='G')
    {
        return true;
    }
    grid[x][y] = '+';
    if(traceMaze(grid,x-1,y)){return true;}
    if(traceMaze(grid,x,y+1)){return true;}
    if(traceMaze(grid,x+1,y)){return true;}
    if(traceMaze(grid,x,y-1)){return true;}
    grid[x][y] = '.';
    return false;
}

int main()
{
    char grid[6][6] = {{'S','X','X','X','X','X'},{'.','.','.','.','.','X'},{'X','.','X','X','X','X'},{'X','.','X','X','X','X'},{'.','.','.','X','.','G'},{'X','X','.','.','.','X'}};
    cout<<"Initial grid is as follows :n";
    printGrid(grid);
    cout<<"nStarting at : (0,0)nTracing the path to the Goaln";
    cout<<traceMaze(grid,0,0)<<"n";
    cout<<"nFinal grid is as follows :n";
    printGrid(grid);
    return 0;
}

附言:我假设迷宫的大小是6X6…

Correct Solution : 

我没有检查我正在通过的"+",以查看最终追踪的路径。

所以现在我在那里应用了一个检查,isValidPoint函数转换为:

bool isValidPoint(char grid[6][6],int x,int y)
{   
    if(x<0 || x>5 || y<0 || y>5)
    {
        return false;
    }
    if(grid[x][y]=='X' || grid[x][y]=='+')
    {
        return false;
    }
    return true;
}

谢谢你们的帮助伙计们:)

我去年在一次全职面试中得到了这个问题。

没有什么可以阻止traceMaze函数无限递归。即,它将从一个网格点到下一个,然后返回到原始网格点。

最简单的解决方法是不将带有"+"的和点视为要进入的有效点(因为您已经在这条路径中找到了)。

黑暗的答案在我看来是有效的。

您的搜索从0,0开始。然后它回到0,1,从那里它回到0,0,再回到0,1…你应该标记你已经访问过的方块,不要再去那里了。'+'很好,但设置后不应该清除它,应该在isValidPoint中检查它。

您正在做的是深度优先遍历迷宫。您正在将.更改为+以跟踪访问的点,但完成后将它们再次更改为.。这就是问题所在。

假设AB是迷宫的相邻细胞。当您遍历A时,将A更改为+并递归遍历其邻居(包括B),然后再次将A更改为.。然后,当您遍历B时,A.,所以您从B再次遍历A,这是不必要的。

这就是为什么递归永远不会结束,并且会出现分段错误。

解决这个问题的一种方法是保留一个单独的6x6阵列来跟踪访问的点。当你处理完一个单元格(即遍历该单元格的所有可能路径)后,将其标记为"已访问"单元格,并且永远不要再访问已访问的单元格。

我把你的迷宫写在一张纸上,用手尝试算法,结果在x=2,y=1处卡住了,你的算法想回到x=1,y=1,回到以前的状态。这种状态当然会进入上述状态,并产生一个无限循环。递归编程的一个重要规则是始终确保所有函数调用的所有执行路径都以返回调用(或类似的)结束

如果你想在这个问题上大做文章,我建议你研究一下最短路径问题的解决方法,例如Dijkstra的算法。