在随机生成的迷宫上使用递归回溯

时间:2014-06-25 16:47:41

标签: c# winforms recursion backtracking recursive-backtracking

我已经编程了大约五年了,我可以毫不费力地创建动态迷宫。 但现在谈到递归回溯,我完全不知道从哪里开始。我已经阅读了很多教程,主题和一些algorhytm wiki(dijkstra&al; algorhytm),但它们对我来说毫无意义。

我知道基本的递归是如何工作的,但是我根本无法理解如果没有(在我看来)存储先前搜索到的路径,或者如果被跟踪的路径突然分裂为两个,会发生什么情况下递归回溯是可能的

我的程序是这样的: 迷宫由484个面板组成(Panel []数组名为mazeTiles)。 有22行,每行有22个面板。 黑色面板背景是墙壁,白色背景是可穿越的。

这是它在运行时的样子(以及只有在从左上角的起始方块(红色)到绿色方块没有有效路径时才会显示的错误消息:

http://postimg.org/image/6c7wgxtz1/

显示的错误信息是" Maze无法解决"即使它可以清楚地解决。此错误消息位于Button2_Click方法中。

以下是我从教程中获取的代码(并已修改),问题肯定位于方法中,但我不知道如何对此进行故障排除。

    private void button2_Click(object sender, EventArgs e)
    {
        int startPosition = 0;

        for (int i = 0; i < mazeTiles.Length; i++)
        {
            if (mazeTiles[i].BackColor == Color.Red)
            {
                startPosition = i;
            }
        }

        bool[] alreadySearched = new bool[484];

        if (!solveMaze(startPosition, alreadySearched))
            MessageBox.Show("Maze can not be solved.");
    }

    private bool solveMaze(int position, bool[] alreadySearched)
    {
        bool correctPath = false;

        //should the computer check this tile
        bool shouldCheck = true;

        //Check for out of boundaries
        if (position >= mazeTiles.Length || position < 0 )
            shouldCheck = false;
        else
        {
            //Check if at finish, not (0,0 and colored light blue)
            if (mazeTiles[position].BackColor == Color.Green)
            {
                correctPath = true;
                shouldCheck = false;
            }
            //Check for a wall
            if (mazeTiles[position].BackColor == Color.Black)
                shouldCheck = false;
            //Check if previously searched
            if (alreadySearched[position])
                shouldCheck = false;
        }
        //Search the Tile
        if (shouldCheck)
        {
            //mark tile as searched
            alreadySearched[position] = true;
            //Check right tile
            correctPath = correctPath || solveMaze(position + 1, alreadySearched);
            //Check down tile
            correctPath = correctPath || solveMaze(position + 22, alreadySearched);
            //check left tile
            correctPath = correctPath || solveMaze(position - 1, alreadySearched);
            //check up tile
            correctPath = correctPath || solveMaze(position - 22, alreadySearched);
        }

        //make correct path gray
        if (correctPath)
            mazeTiles[position].BackColor = Color.Gray;

        return correctPath;
    }

我需要找到并存储所有路径或最快的路径(并且只记录最快的路径)从红色方块到绿色路径。绿色方块是静态的,但红色方块和整个迷宫是随机生成的。

2 个答案:

答案 0 :(得分:1)

已经两年了,这篇文章没有得到答案。我当时正在寻找的答案是一个解释,让我意识到递归回溯是如何工作的。我很难弄清楚该方法如何知道它以前的位置,似乎没有存储访问区域以防止反复出现(无限循环)。但是一旦我意识到它是如何工作的,我立即想出了如何编写代码。

因此,如果有人在想到同样的事情时偶然发现了这一点。理解递归回溯的一种简单方法是理解递归方法的工作原理。递归方法一直在反复调用,直到找到正确的答案。递归回溯一直在调用自身,以便找到正确的答案。所以很多基本的递归方法都取而代之,因此通常一次只有一个实例,而递归回溯方法往往叠加在一起。

当解决这个难题时,该方法一直在自己内部(起始式)一遍又一遍地调用自己,同时不断向一个方向迈出一步,直到在那个方向上没有更多的步骤。当那个实例结束并且之前调用它的那个实例结束时。一旦该实例结束,那之前的那个将继续(并且它可以使它成为一千个自己的例子)。

如果您仍然无法理解,请想一想您现在如何被困在迷宫中。你有一个超级大国而且没有飞行,它是克隆。所以你继续前进,直到路径分裂。这是当你克隆自己并在你的位置上发送它的时候,而原始你不会移动,直到克隆找到出口或达到死胡同,这是当克隆传送回去的时候给你并分享他的信息。但是如果你的克隆也遇到分裂的路径,他会克隆自己并等待他的克隆返回迷宫的知识。克隆的克隆也可以根据路径分裂的次数生成无数个克隆。归根结底,所有这些综合知识都会回归到你身边。当你知道在哪里找到迷宫的出口时,那就是那个。

答案 1 :(得分:0)

你的问题太宽泛了。您需要发布一个特定问题。看起来你正在尝试完成家庭作业。

您的问题需要调试,这需要有人来运行您的代码。你可能最好只包括一个代码链接,以便有人可以运行它,如果他们想花时间去做。

您可能需要一个类级属性来存储最快的路径,因为您已经返回了一个bool,或者您可以使用一个out变量。您传递给递归方法的数组将存储我假设的所有先前检查过的索引。