您将如何在 Haskell 中实施启发式搜索?
How would you implement a heuristic search in Haskell?
在 Haskell 或其他一些函数式编程语言中,您将如何实现启发式搜索?
以搜索 space 为例,九拼图是一个 3x3 的网格,有 8 个方块和 1 个孔,将方块移动到孔中,直到正确拼出一张图片。启发式是 "Manhattan heuristic",它评估棋盘位置加上每个方块与其目标位置的距离,以水平方向的方块数加上每个方块需要移动的垂直方块数作为距离到正确的位置。
我一直在阅读 John Hughes 关于漂亮印刷的论文,因为我知道漂亮印刷会回溯以找到更好的解决方案。我试图了解如何按照这些思路概括启发式搜索。
===
请注意,我在这里的最终目标不是为 9 谜题编写求解器,而是学习一些用 FP 语言编写高效启发式搜索的通用技术。我也有兴趣了解是否有代码可以在更广泛的 class 此类问题中泛化和重复使用,而不是解决任何特定问题。
例如,搜索 space 的特征可以是一个将状态映射到状态列表的函数,以及一些 'operation' 描述一个状态如何转换为另一个状态的函数。也可能有一个目标函数,将状态映射到 Bool,指示何时达到目标状态。当然,启发式函数将一个状态映射到一个数字,反映了它的估计得分。搜索的其他描述也是可能的。
我认为它不一定非常特定于 FP 或 Haskell(除非您将列表用作 "multiple possibility" 单子,如 Learn You A Haskell For Great Good 中)。
一种方法是编写一个采用以下内容的递归函数:
- 当前状态(即电路板配置)
- 可能是一些路径元数据,例如,从初始配置开始的步数(这只是递归深度),或者已经考虑的所有状态的记忆映射
- 可能是一些决定、元数据,例如伪随机数生成器
在每次递归调用中,函数都会获取状态,并检查它是否是所需的结果。如果不是它会
如果它使用记忆图,请检查是否已经考虑过选择
如果使用递归步数,检查是否进一步选择
如果它决定递归地调用自己从这个状态发出的可能选择(例如,如果有不同的瓷砖可以被推入洞中),它可以按照基于的顺序这样做在启发式上(或者可能是基于启发式的顺序伪随机)
函数将 return 是否成功,如果使用它们,更新版本的记忆映射 and/or 伪随机数生成器。
在 Haskell 或其他一些函数式编程语言中,您将如何实现启发式搜索?
以搜索 space 为例,九拼图是一个 3x3 的网格,有 8 个方块和 1 个孔,将方块移动到孔中,直到正确拼出一张图片。启发式是 "Manhattan heuristic",它评估棋盘位置加上每个方块与其目标位置的距离,以水平方向的方块数加上每个方块需要移动的垂直方块数作为距离到正确的位置。
我一直在阅读 John Hughes 关于漂亮印刷的论文,因为我知道漂亮印刷会回溯以找到更好的解决方案。我试图了解如何按照这些思路概括启发式搜索。
===
请注意,我在这里的最终目标不是为 9 谜题编写求解器,而是学习一些用 FP 语言编写高效启发式搜索的通用技术。我也有兴趣了解是否有代码可以在更广泛的 class 此类问题中泛化和重复使用,而不是解决任何特定问题。
例如,搜索 space 的特征可以是一个将状态映射到状态列表的函数,以及一些 'operation' 描述一个状态如何转换为另一个状态的函数。也可能有一个目标函数,将状态映射到 Bool,指示何时达到目标状态。当然,启发式函数将一个状态映射到一个数字,反映了它的估计得分。搜索的其他描述也是可能的。
我认为它不一定非常特定于 FP 或 Haskell(除非您将列表用作 "multiple possibility" 单子,如 Learn You A Haskell For Great Good 中)。
一种方法是编写一个采用以下内容的递归函数:
- 当前状态(即电路板配置)
- 可能是一些路径元数据,例如,从初始配置开始的步数(这只是递归深度),或者已经考虑的所有状态的记忆映射
- 可能是一些决定、元数据,例如伪随机数生成器
在每次递归调用中,函数都会获取状态,并检查它是否是所需的结果。如果不是它会
如果它使用记忆图,请检查是否已经考虑过选择
如果使用递归步数,检查是否进一步选择
如果它决定递归地调用自己从这个状态发出的可能选择(例如,如果有不同的瓷砖可以被推入洞中),它可以按照基于的顺序这样做在启发式上(或者可能是基于启发式的顺序伪随机)
函数将 return 是否成功,如果使用它们,更新版本的记忆映射 and/or 伪随机数生成器。