我已经编程了大约五年了,我可以毫不费力地创建动态迷宫。 但现在谈到递归回溯,我完全不知道从哪里开始。我已经阅读了很多教程,主题和一些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;
}
我需要找到并存储所有路径或最快的路径(并且只记录最快的路径)从红色方块到绿色路径。绿色方块是静态的,但红色方块和整个迷宫是随机生成的。
答案 0 :(得分:1)
已经两年了,这篇文章没有得到答案。我当时正在寻找的答案是一个解释,让我意识到递归回溯是如何工作的。我很难弄清楚该方法如何知道它以前的位置,似乎没有存储访问区域以防止反复出现(无限循环)。但是一旦我意识到它是如何工作的,我立即想出了如何编写代码。
因此,如果有人在想到同样的事情时偶然发现了这一点。理解递归回溯的一种简单方法是理解递归方法的工作原理。递归方法一直在反复调用,直到找到正确的答案。递归回溯一直在调用自身,以便找到正确的答案。所以很多基本的递归方法都取而代之,因此通常一次只有一个实例,而递归回溯方法往往叠加在一起。
当解决这个难题时,该方法一直在自己内部(起始式)一遍又一遍地调用自己,同时不断向一个方向迈出一步,直到在那个方向上没有更多的步骤。当那个实例结束并且之前调用它的那个实例结束时。一旦该实例结束,那之前的那个将继续(并且它可以使它成为一千个自己的例子)。
如果您仍然无法理解,请想一想您现在如何被困在迷宫中。你有一个超级大国而且没有飞行,它是克隆。所以你继续前进,直到路径分裂。这是当你克隆自己并在你的位置上发送它的时候,而原始你不会移动,直到克隆找到出口或达到死胡同,这是当克隆传送回去的时候给你并分享他的信息。但是如果你的克隆也遇到分裂的路径,他会克隆自己并等待他的克隆返回迷宫的知识。克隆的克隆也可以根据路径分裂的次数生成无数个克隆。归根结底,所有这些综合知识都会回归到你身边。当你知道在哪里找到迷宫的出口时,那就是那个。
答案 1 :(得分:0)
你的问题太宽泛了。您需要发布一个特定问题。看起来你正在尝试完成家庭作业。
您的问题需要调试,这需要有人来运行您的代码。你可能最好只包括一个代码链接,以便有人可以运行它,如果他们想花时间去做。
您可能需要一个类级属性来存储最快的路径,因为您已经返回了一个bool,或者您可以使用一个out变量。您传递给递归方法的数组将存储我假设的所有先前检查过的索引。