如何在使用 BFS 找到最短路径后重建 2d 迷宫的路径

时间:2021-07-31 02:52:08

标签: c++

我已经在 C++ 中实现了呼吸优先搜索算法,如下所示,我知道该算法有效并找到从给定房间到其中一个出口的最短路径。但是由于算法的性质,它没有找到实际路径,而是找到从开始节点到结束节点所采取的步数。

我正在尝试重建使用此算法找到的最短路径。我在一个与我的迷宫大小相同的矩阵中为每个访问的节点存储了父节点的记录。由于每个节点都有一个 x 和 y 坐标,我制作了两个父矩阵,一个用于 x,一个用于 y(不确定这是否是正确的方法)。

我在实现重建路径的函数时遇到问题。从我读过的内容来看,我假设从父矩阵中的结束节点循环到开始节点,但我实际上如何做到这一点?我什至不知道如何概念化这样做。

int bfs(string maze[row][col],bool visited[row][col],int prevx[row][col],int prevy[row][col],int x,int y,int &endx, int &endy){
int nodes_left = 1; // tracks how many nodes we need to dequeue before taking a step
int move_count = 0; //tracks the number of steps taken
bool foundExit = false;
int curx, cury;
rq.push(y);
cq.push(x);
visited[y][x] = true;
while (rq.size()>0){
    cury = rq.front();
    curx = cq.front();
    rq.pop();
    cq.pop();
    if (maze[cury][curx] == " E2"){
        foundExit = true;
        endx = 0;
        endy = 8;
        break;
    }
    if(maze[cury][curx] == " E4"){
        foundExit = true;
        endx = 12;
        endy = 14;
        break;
    }
    check_nodes(maze,prevx,prevy,visited,curx,cury);
    //tracking the number of steps to exit the maze
    nodes_left--;
    if (nodes_left == 0){
        nodes_left = next_nodes;
        next_nodes = 0;
        move_count++;
    }
}
if(foundExit){
    return move_count;
}
return -1;

}

void check_nodes(string maze[row][col],int prevx[row][col],int prevy[row][col],bool visited[row][col],int curx, int cury){
int newy,newx;
//checking all 4 possible directions
for (int i = 0; i< 4; i++){
    newy = cury + dr[i];        //updating new y coordinate corresponding to the row
    newx = curx + dc[i];        //updating new x coordinate corresponding to the column
    if (validMove(maze,visited,newx,newy)){ //checking if move is valid, i.e not out of bounds, visited, or blocked.
        rq.push(newy);           //adding new coordinates to the queue
        cq.push(newx);
        visited[newy][newx] = true;  //marking visited to ensure that it cannot be added to the queue multiple times
        prevy[newy][newx] = cury;
        prevx[newy][newx] = curx;
        next_nodes++;               //moving to the next layer of nodes
    }
}

}

1 个答案:

答案 0 :(得分:0)

你的代码就快到了。你只需要按照你所说的去做:重建从头到尾的路径。我认为您正在努力实现这一点。我将使用您使用的变量编写该部分的代码。我将使用 vector<pair<int, int> > 来构建路径。这个向量的每个元素都是一对,其中第一个值是 x 坐标,第二个值是 y 坐标。由于路径是从头到尾构建的,所以应该在算法结束时反转。

vector<pair<int, int> > path;
int endx = 0, endy = 8; // this is one of the exit coordinates according your code
int startx = 0, starty = 0; // this is not necessarily your start position
int curx = endx, cury = endy; // current position while building the path backwards
while(curx != startx || cury != starty) {
    path.push_back(make_pair(curx, cury));
    int tempx = prevx[curx][cury]; // notice that is necessary to use temporal variable
    int tempy = prevy[curx][cury]; // to prevent overwriting curx that was immediately used
    curx = tempx;
    cury = tempy;
}
reverse(path.begin(), path.end()); // reversing the path to its correct order