你没有太多的解决方案:基本上,探索无环迷宫是像做了深度优先搜索在覆盖树,每个路口是一个节点。
您可以随时构建树,并使用该信息来浏览它,但这会很单调乏味效率不高。
深度优先搜索的常用方法是推动堆栈中的所有节点进行检查,拉动一个并再次推动,直到达到目标。但是你会得到很多节点堆积起来,一旦找到目标节点,就不能使用堆栈来知道你遵循的是哪条路径,这意味着你需要在其他地方存储这些信息。
这可能是更好的保持栈解决方案和标签节点在你的筹码来表示一个分支,和方向(即其子树)的分支已经探索(或路径剩下)。如果您在相同的顺序做的探索始终,该标签可以简单地将一个数字:
或更好的是枚举。
当找到死角时,只需展开堆栈直到找到其中一个节点,然后尝试新的方向。如果所有方向都已经尝试过,换句话说,如果没有方向,请再次放松。
enum Branch {
LEFT,
FORWARD,
RIGHT,
BACKTRACK
};
struct BacktrackException{
};
template <typename MazeMove>
struct StackNode {
MazeMove move;
Branch branch;
StackNode(MazeMove m): move(m), branch(LEFT) {}
MazeMove nextBranch(){
switch(branch){
case LEFT:
if (move.can_left()){
branch = FORWARD;
return move.left();
}
case FORWARD:
if (move.can_forward()){
branch = RIGHT;
return move.forward();
}
case RIGHT:
if (move.can_right()){
branch = BACKTRACK;
return move.right();
}
default:
throw BacktrackException();
}
}
};
上面的代码提供与栈使用的可能的“MazeMove”类,它保持跟踪所尝试的方向的一个包装。 nextBranch方法返回下一个可能的移动,或者引发异常。
好处是你的堆栈不会被未经测试的移动破坏。每当你到达一个新的位置时,你推动一个StackNode
,当它的选项全部被测试出来时,将其展开。当你到达迷宫出口时,你的堆栈只包含需要的移动。
“我需要一个堆栈...所以没有递归” - 这是没有意义的。谨慎解释? – 2013-04-20 14:47:15
[迷宫问题和递归回溯算法](http:// stackoverflow。com/questions/4402846/maze-problem-and-recursive-backtracker-algorithm) – 2013-04-20 14:47:53
@ Moo-Juice这不是一个好的重复。这是一个迷宫解决的问题,但具体问题是完全不同的。 – 2013-04-20 14:50:48