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

C# 在随机生成的迷宫上使用递归回溯,c#,winforms,recursion,backtracking,recursive-backtracking,C#,Winforms,Recursion,Backtracking,Recursive Backtracking,我已经做了大约五年的编程了,我在创建动态迷宫方面没有遇到任何问题。 但现在说到递归回溯,我完全不知道从哪里开始。我读过很多教程、主题和一些算法论维基(dijkstra的算法论),它们对我来说毫无意义 我知道基本递归是如何工作的,但我根本无法理解,如果不(在我看来)存储以前搜索的路径,或者如果正在跟踪的路径突然一分为二,那么递归回溯是如何可能的 我的程序是这样工作的: 迷宫由484个面板组成(面板[]数组名为mazeTiles)。 共有22行,每行可容纳22个面板。 黑色的面板背景是墙,白色的背景

我已经做了大约五年的编程了,我在创建动态迷宫方面没有遇到任何问题。 但现在说到递归回溯,我完全不知道从哪里开始。我读过很多教程、主题和一些算法论维基(dijkstra的算法论),它们对我来说毫无意义

我知道基本递归是如何工作的,但我根本无法理解,如果不(在我看来)存储以前搜索的路径,或者如果正在跟踪的路径突然一分为二,那么递归回溯是如何可能的

我的程序是这样工作的: 迷宫由484个面板组成(面板[]数组名为mazeTiles)。 共有22行,每行可容纳22个面板。 黑色的面板背景是墙,白色的背景是可以穿过的

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

显示的错误消息是“迷宫无法解决”,即使它可以清楚地解决。此错误消息位于按钮2\u单击方法中

下面是我从一个教程中获得的代码(并进行了修改),问题肯定出在方法中,但我不知道如何解决这个问题

    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;
    }
private void按钮2\u单击(对象发送者,事件参数e)
{
int startPosition=0;
for(int i=0;i=mazeTiles.长度| |位置<0)
shouldCheck=false;
其他的
{
//检查完工时是否为非(0,0和浅蓝色)
if(mazeTiles[position].BackColor==Color.Green)
{
correctPath=true;
shouldCheck=false;
}
//检查墙壁
if(mazeTiles[position].BackColor==Color.Black)
shouldCheck=false;
//检查以前是否搜索过
如果(已拱形[位置])
shouldCheck=false;
}
//搜索瓷砖
如果(应检查)
{
//将瓷砖标记为已搜索
alreadySearched[位置]=真;
//检查右瓷砖
correctPath=correctPath | | solveMaze(位置+1,已拱形);
//检查瓷砖
correctPath=correctPath | | solveMaze(位置+22,已拱形);
//检查左边的瓷砖
correctPath=correctPath | | solveMaze(位置-1,已拱形);
//检查瓷砖
correctPath=correctPath | | solveMaze(位置-22,已拱形);
}
//使正确的路径变为灰色
如果(正确路径)
mazeTiles[位置]。背景色=颜色。灰色;
返回正确路径;
}

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

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

您的问题需要调试,这需要有人运行您的代码。您最好只包含一个指向代码的链接,这样如果有人想花时间运行代码,就可以运行它


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

已经两年了,这篇文章没有得到答案。答案是当时我在寻找一个解释,使我意识到递归回溯是如何工作的。我很难弄清楚这个方法如何知道它以前在哪里,似乎没有存储访问的区域,以防止重复同样的方式(无限循环).但一旦我意识到它是如何工作的,我马上就明白了如何编写代码

因此,如果有人在想同样的事情时偶然发现了这一点。理解递归回溯的一个简单方法是理解递归方法是如何工作的。递归方法不断地调用自己,直到找到正确的答案。递归回溯不断地在自己内部调用自己,以便找到正确的答案。所以很多许多基本的递归方法替换了itelf,因此一次通常只有一个实例,而递归回溯方法通常是堆叠在彼此的顶部

当解决这个难题时,这个方法不断地在自己内部调用自己(初始阶段风格),同时不断地在一个方向上放置一个步骤,直到该方向上没有更多的步骤。此时该实例结束,调用它的前一个实例继续运行。一旦该实例结束,之前的那个实例将继续(而且它可以自己制作一千部电影)

如果你仍然无法理解,想想你现在是如何被困在迷宫中的。你有一个超能力,它不是飞行,而是克隆。所以你一直向前走,直到路径分裂。这时你克隆自己,让他在你的位置上前进,而原来的你直到克隆人找到你才移动