这是一个我可以很容易地以非功能性方式解决的问题。
但是在Haskell中解决这个问题给了我很大的麻烦。在涉及函数式编程时,我缺乏经验肯定是一个原因。
问题:
我将2D场分成相同大小的矩形。一个简单的网格。一些矩形是空的空间(并且可以通过)而其他矩形是无法通过的。给定起始矩形 A 和目标矩形 B ,我如何计算两者之间的最短路径?只能垂直和水平移动,步骤一个矩形大。
我如何在Haskell中完成此任务?代码片段肯定是受欢迎的,但肯定不是必要的。并且非常欢迎链接到更多资源!
谢谢!
答案 0 :(得分:12)
我将网格表示为列表,列出[[Bool]]
。我定义了一个函数来知道网格元素是否已满:
type Grid = [[Bool]]
isFullAt :: Grid -> (Int, Int) -> Bool -- returns True for anything off-grid
然后我定义了一个查找邻居的函数:
neighbors :: (Int, Int) -> [(Int, Int)]
要查找point
的非完整邻居,您可以使用filter (not . isFullAt) $ neighbors point
进行过滤。
此时我将定义两个数据结构:
Maybe Cost
仅使用堆中的起始方 A 进行初始化,且成本为零。
然后循环如下:
c
,并将所有非完整邻居添加到堆中,费用为c+1
。当堆为空时,您将获得所有可到达点的成本,并且可以在有限映射中查找 B 。 (这个算法可能被称为“Dijkstra算法”;我已经忘记了。)
您可以在Data.Map
中找到有限地图。我假设在庞大的库中有一个堆(也就是优先级队列),但我不知道在哪里。
我希望这足以让你开始。
答案 1 :(得分:3)
嗯,您的类型将决定您的算法。
您想用什么数据类型来表示网格?一个二维数组?列表清单?一颗树?图表?
如果您只想在有向图中使用最短路径,那么最好使用FGL(功能图包)中的内容。