所以我正试图创建一个迷宫求解程序来求解X和O的迷宫。我想做的是创建一类点,这样我就可以创建一个二维点数组,这将允许打印到输出页面,并实现相对简单的堆栈。
我想在实际程序中实现的一般想法的最简单算法应该是:
1) Move forward
2) Are you at a wall?
2a) If yes, turn left
3) Are you at the finish?
3a) If no, go to 1
3b) If yes, solved
但我很难想出一个更深入的算法,也很难找到我的Points类。我知道对于点,我应该设置X坐标,设置Y坐标,以及两者的getter。你认为我需要比这两种方法更多的方法吗?比如,我应该创建一个方法,将x坐标和y坐标作为参数,这样我就可以将它们作为一个参数推到一起,而不是单独设置x和y吗?
这就是一个样本迷宫的样子,你从右下角开始,试图遍历到左上角,X是墙,O是迷宫中的开放空间:
O O O O O X O
X X O X O O X
O X O O X X X
X X X O O X O
X X X X O O X
O O O O O O O
X X O X X X O
你确定你的算法能解决任何迷宫吗?我认为它会被困在这个简单的模型中(其中S是开始,F是结束):
xxxxxxxxxx
Sooooooxxx
xxxxxxoxxx
xxxxxxFxxx
你的算法会沿着第一个大厅往下走,直到它面对秋天,左转,面对"北"墙,再次左转,然后沿着第一个走廊往回走,在那里它会再次左转两次,并不断重复这个问题。
右手规则算法(请参阅维基百科页面,以及其他章节了解更多的迷宫算法)应该可以解决任何没有循环的迷宫,并且应该很容易在java中实现。
您可以使用
Stack<Point> points = new Stack<>();
// add a point
Point p = new Point(x, y);
if (points.contains(p))
// been here before, in circles.
else
points.add(p);
对于算法部分,优选通过堆栈进行深度优先递归。大致如下:
currentSpot = (0,0) // The starting point //
while(! currentSpot.isExit()) {
if (! currentSpot.left().isWall()) stack.push(currentSpot.left());
if (! currentSpot.forward().isWall()) stack.push(currentSpot.forward());
if (! currentSpot.right().isWall()) stack.push(currentSpot.right());
currentSpot = stack.pop(); // Get the next location //
}
你会希望你的点类在每个给定的方向上返回下一个点(向后除外),并检测你何时到达迷宫的边缘。您可能想要一个包含所有点、进行打印、存储X/O等的Maze类。因此,您可能会将初始currentSpot=(0,0)替换为currentSpot=Maze.getStartingSpot();
对于您的算法,您不需要堆栈。只有当您使用回溯来撤消遍历决策时,才需要一个堆栈。
对于算法,您可以使用回溯(EDIT尽管它与您的总体想法不太匹配,但是,如果您只想解决迷宫问题,则可以依赖调用堆栈。
使用墙跟随器算法:http://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower
我上学的时候我们曾经解决过这个问题,我们使用了类似于右手/左手规则的解决方案。我相信我们是在学习链表时这样做的。简而言之,算法是这样的:
- 向左走。如果可能,重复
- 如果没有,就直走。如果可能,返回步骤1
- 如果没有,请向右走。如果可能,返回步骤1
每走一步,你还要检查一下你所站的地方是否是终点。如果你无法继续(即无法向左、直行或向右),你可以将你所站的位置标记为"已访问"并后退。冲洗并重复。