【发布时间】:2014-09-25 09:45:41
【问题描述】:
我正在尝试基于 Haskell 中以下链接中描述的算法实现迷宫求解器。
http://www.cs.bu.edu/teaching/alg/maze/
我对haskell和函数式编程很陌生,我基本上尝试按照链接中描述的方式编写算法,我尝试在网上浏览许多其他资源,但我被困在目标时步行停止的部分(它不会停止,它会回到原点)到达,我无法取消标记迷宫中的错误位置。
迷宫的样子
.########
.......#.
#.####..#
#.#######
...#.G...
##...####
#..######
我的代码如下
findPath :: Int->Int->Maze->(Bool,Maze)
findPath x y maze
| not (isSafe maze x y) = (False,maze)
| isChar maze x y 'G' = trace ("Solution: "++ show maze)(True,maze)
| isChar maze x y '#' = (False,maze)
| isChar maze x y '!' = (False,maze)
| fst walkNorth = (True,markedList)
| fst walkEast = (True,markedList)
| fst walkSouth = (True,markedList)
| fst walkWest = (True,markedList)
| otherwise = (False,unMarkedList)
where markedList = replaceCharInMaze maze x y '+'
unMarkedList = replaceCharInMaze maze x y '!'
walkNorth = findPath x (y-1) markedList
walkEast = findPath (x+1) y markedList
walkSouth = findPath x (y+1) markedList
walkWest = findPath (x-1) y markedList
isSafe 函数只检查边界,isChar 只是在给定 x,y 位置匹配的字符,replaceCharInMaze 函数用提供的字符替换 x,y 位置的字符。
isSafe :: [String]->Int->Int->Bool
isSafe list x y
| y >= 0 && y < length (head list) && x >= 0 && x < length list && (isChar list xy '.' || isChar list x y 'G') = True
| otherwise = False
所以,我有两个问题
我无法将在否则情况下进行的取消标记持续到下一次递归调用,我如何继续保持迷宫的状态,以便即使是未标记的状态也是一部分解决方案?
那么随着算法的进行,一直走到目标又回到起点,如何阻止这种情况的发生?
由于我是 Haskell 和算法的新手,我查看了诸如状态单子之类的主题,这似乎是解决方案,但我不太确定是否继续进行,我还尝试查看其他堆栈溢出帖子,但找不到任何可以帮助我的东西。
trace语句中得到的迷宫输出如下
+++#..###..#.
.#+++#+++.##.
####+#+#+#-##
...#+++#+#...
.#.####++.##.
.#G+++++#....
.############
....####.....
但它并不止于此,它会回溯到原点并将输出打印为
+..#..###..#.
.#...#....##.
####.#.#.#.##
...#...#.#...
.#.####...##.
.#G.....#....
.############
....####.....
【问题讨论】:
标签: haskell recursion functional-programming maze