Algorithm 使用Haskell查找网格上两点之间的最短路径

Algorithm 使用Haskell查找网格上两点之间的最短路径,algorithm,haskell,shortest-path,referential-transparency,Algorithm,Haskell,Shortest Path,Referential Transparency,这是一个我可以很容易地用非功能性的方式解决的问题 但是在Haskell解决这个问题给了我很大的麻烦。我对函数式编程缺乏经验肯定是一个原因 问题是: 我有一个2D区域,被分成大小相等的矩形。一个简单的网格。一些矩形是空的空间(可以通过),而另一些则无法通过。给定起始矩形a和目标矩形B,如何计算两者之间的最短路径?移动只能在垂直和水平方向上进行,在单个大矩形中进行 我将如何在哈斯克尔实现这一点?代码片段当然是受欢迎的,但也不是必需的。并且进一步的资源链接也非常欢迎 谢谢 嗯,你的类型将决定你的算法

这是一个我可以很容易地用非功能性的方式解决的问题

但是在Haskell解决这个问题给了我很大的麻烦。我对函数式编程缺乏经验肯定是一个原因

问题是:

我有一个2D区域,被分成大小相等的矩形。一个简单的网格。一些矩形是空的空间(可以通过),而另一些则无法通过。给定起始矩形a和目标矩形B,如何计算两者之间的最短路径?移动只能在垂直和水平方向上进行,在单个大矩形中进行

我将如何在哈斯克尔实现这一点?代码片段当然是受欢迎的,但也不是必需的。并且进一步的资源链接也非常欢迎


谢谢

嗯,你的类型将决定你的算法

您希望使用什么数据类型来表示网格?二维数组?名单?一棵树?图表


如果您只想在有向图中使用最短路径,那么最好使用FGL(functional graph package)中的内容。

我将网格表示为列表列表,键入
[[Bool]]
。我会定义一个函数来知道网格元素是否已满:

type Grid = [[Bool]]
isFullAt :: Grid -> (Int, Int) -> Bool  -- returns True for anything off-grid
然后我将定义一个查找邻居的函数:

neighbors :: (Int, Int) -> [(Int, Int)]
要查找
的非完整邻域,可以使用
过滤器(not.isFullAt)$neights point
进行过滤

此时,我将定义两种数据结构:

  • 将每个点映射到
    可能成本
  • 将具有已知成本的所有点存储在堆中
仅使用堆中的起始方块A进行初始化,成本为零

然后循环如下:

  • 从堆中删除最小成本平方
  • 如果它不在有限映射中,则添加它及其cost
    c
    ,并使用cost
    c+1
    将所有非满邻居添加到堆中
当堆为空时,您将拥有所有可达点的成本,并且可以在有限映射中查找B。(这个算法可能被称为“Dijkstra算法”;我已经忘记了。)

您可以在
Data.Map
中找到有限映射。我假设在这个庞大的库中的某个地方有一个堆(也称为优先级队列),但我不知道在哪里


我希望这足以让你开始学习。

这听起来肯定是Dijkstra的算法,或者至少是它的一个变体。听起来像是a*算法。(我似乎无法正确发布维基百科链接)。