【问题标题】:Recording a maze path solution with a stack用栈记录迷宫路径解
【发布时间】:2012-01-09 08:38:35
【问题描述】:

我要以某种方式使用堆栈的链表实现来生成迷宫的解决方案。迷宫是从 .txt 文件中读取的,由 0 代表开放空间和 1 代表墙壁。

我尝试使用的算法是:

While Not At End
    If Can Go North
        Go North
    ElseIf Can Go East
        Go East
    ElseIf Can Go South
        Go South
    ElseIf Can Go West 
        Go West
    EndIf
Wend

我一直在尝试的方式依赖于在数组索引中执行的 ++ 操作。我不知道数组下标运算符 [ 优先于 ++ 所以现在我需要重新考虑解决方法。在这样做之前,我想确保这种方法甚至可以首先工作。到目前为止,任何人都可以看看我的算法代码并提供一些反馈吗? (注意:我仍然需要添加一些代码来跟踪路径以避免某种类型的无限循环)

bool notSolved = true;
        int path = 0;
        row = 0;
        col = 0;

        rowStack.push(row);
        colStack.push(col);

        while (notSolved){

        //(from perspective of person looking at maze on screen)
        if (maze[row--][col] == 0){//if you can go up, go up
        rowStack.push(row);
        colStack.push(col);
        path++;
        }
        else if (maze[row][col++] == 0){//else if you can go right, go right
        rowStack.push(row);
        colStack.push(col);
        path++;
        }
        else if (maze[row++][col] == 0){//else if you can go down, go down
        rowStack.push(row);
        colStack.push(col);
        path++;
        }
        else if (maze[row][col--] == 0){//else if you can go left, go left
        rowStack.push(row);
        colStack.push(col);
        path++;
        }

            if((maze[row][col] == 0) && (row == (size - 1))){//if we reached an exit
                cout << "Solution Path:" << endl;
                for (int i = 0; i < path; i++){
                    cout << "row:" << rowStack.top() << " col:" << colStack.top() << endl;
                    rowStack.pop();
                    colStack.pop();
                }
            notSolved = false;
            }
        }

在 ++ 之前执行 [ 的问题:

任何帮助表示赞赏,谢谢!

【问题讨论】:

  • 递归是你的朋友。
  • 您有什么具体问题吗?
  • 我觉得这个算法不是特别好,比如你在水平隧道里碰到右边的墙,你会永远从右到左来回弹跳。
  • @Erix 搜索广度优先在迷宫中效果更好,因此在这种情况下,队列可能是比递归更好的“朋友”。即使您决定采用深度优先,使用堆栈和“while”循环而不是递归可能会更好。由于搜索空间随着 N^2 增长,递归调用中溢出堆栈的危险变得非常现实。

标签: c++ algorithm stack maze


【解决方案1】:

++-- 实际上修改了 row/col 变量。我想你想做maze[row - 1][col] == 0,然后一旦你移动了,更新你的行位置。

【讨论】:

    【解决方案2】:

    您的算法在某些具有圆形路径的迷宫中不起作用:一旦您进入其中一个迷宫,您就会陷入困境。要解决此问题,您需要添加一个布尔数组visited[R][C][DIR],其中 DIR 是一个从零到三的数字,表示一个方向。当您在方向 [d] 上离开单元格 [r][c] 时,将visited[r][c][d] 设置为 true。下次你访问同一个单元格时,看看你之前是否离开过同一个方向;如果你这样做了,请跳过那个方向,然后继续下一个方向。

    【讨论】:

    • 嗯,我想我让访问的数组工作了,但我遇到了问题。有没有更好的方法在 if 语句中实现它这是问题:imgur.com/5rstN,向右,向下,向右,向右,撞到墙上然后转身卡住。这是我的新代码:pastebin.com/uhp9MKfc
    • @mwmnj 用于检查您是否去过某个地点的代码看起来不错,现在您需要实现回溯,这是“遇到困难时该怎么办”的花哨名称。在你的情况下,你需要从你的 rowStack/colStack 中弹出最后一步,回到上一个单元格,然后继续你以前没有尝试过的下一个方向。
    • hmm,我最初的想法是在末尾添加一个 else:else{//if stuck rowStack.pop(); colStack.pop(); row = rowStack.top(); col = colStack.top(); } 但现在似乎要做的就是从堆栈顶部弹出每一步,直到它为空
    • @mwmnj 在调用 pop 之前,您需要查看顶部。您还需要在弹出堆栈之前检查堆栈是否为空。最后,你需要将你的 ifs 包含在一个循环中,因为一旦你回溯,你需要继续朝着你没有尝试过的下一个方向前进。
    • 调用pop前需要注意什么?我正在尝试做的是让它弹出堆栈,然后将 row 和 col 重新分配给先前的空格值,以便它会去尝试它尚未尝试过的任何方向。我的 if 语句包含在一个循环中:Wnotsolved: pastebin.com/VSE2qBDu
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-24
    • 1970-01-01
    相关资源
    最近更新 更多