【问题标题】:Heuristic Function for Rubik's cube in A* algorithm Artificial IntelligenceA* 算法中魔方的启发式函数 人工智能
【发布时间】:2020-05-24 13:47:20
【问题描述】:

所以我正在尝试通过使用 C++ 的不同算法来解决魔方。我已经尝试过迭代深化搜索 (IDS) 并且做对了,但现在我陷入了 A* 算法。 我做了一些研究,发现立方体角落和边缘的 3D 曼哈顿距离是开发 A* 启发式的方法之一,但我不知道它是如何编码的。 你们能否帮助或指导我如何开发定义上可接受的功能?

我正在寻找可以帮助我摆脱这个困境的所有建议。谢谢。

【问题讨论】:

    标签: c++ artificial-intelligence a-star heuristics rubiks-cube


    【解决方案1】:

    IDA* 是解决魔方的最佳算法之一,因为状态空间很大,并且如果您进行适当的移动修剪,则不会有很多重复项。要获得高效的求解器,您需要移动修剪和良好的启发式算法。通常每个面有 3 次移动 - 向前/向后 90 度和 180 度。 6个面有18个动作。

    1. 简单的移动修剪:如果你通过保留一个历史移动来对你的移动进行一些简单的修剪,你可以将魔方的分支因子从 18 缩小到 15 左右。因为任何单一的移动都可以得到一个面在任何配置中,您都不应该连续两次移动同一张脸。在第一步之后,将有 5 个面,每个面 3 步 = 每步 15 步。

    2. 高级移动修剪:让三个面为“第一”面,其中三个为“第二”面,其中第二个面与第一个面相对。这里的规则是,在您移动第一个面之后,您可以移动任何其他面 - 所以会有 15 次移动。但是,在您移动第二张脸之后,您不能再次移动同一张脸或相反的第一张脸。在这种情况下,分支因子为 12。总的分支因子约为 13。

    3. 启发式:Pattern Databases(PDB)为魔方提供了很好的启发式。例如,您所做的是忽略边缘,然后彻底解决所有角落,将结果存储在哈希表中。 (使用完美的散列函数,然后会有一个独特的紧凑映射,它非常节省内存。)有 8800 万个组合和少于 16 个值,您可以将其存储在 44 MB 的内存中。当您想要某个状态的启发式方法时,您只需使用哈希函数在表中查找角点配置,其中包含解决该配置所需的移动总数。对于该问题,这是一个可接受的(且一致的)启发式方法。除此之外,您可能想要做边缘,但 12 边缘 PDB 需要 500GB 的内存来存储,并且可能不适合内存。所以,你可以做边的子集。您还可以使用立方体对称性和许多其他技巧来获得更好的启发式值。但是,通过良好的并行 IDA* 实现和一些大型 PDB,您可以优化解决随机魔方实例。

    有很多关于这个主题的研究论文 - 我建议使用谷歌学者在线查找。

    如果您想从更简单的开始,以下是如何实现“更简单”的启发式方法:

    1. 对于立方体中的每个角/边,计算自己需要移动多少次才能到达目标位置/方向。将其添加到所有立方体上。

    2. 由于立方体的面每转一圈会移动 4 个角和 4 个边,因此将第一步中的数字除以 8。然后这是该问题的一个可接受的启发式方法。

    如果您忽略方向,则每个立方体最多需要两次移动才能到达其目标位置,这意味着您的最终启发式将小于 2。将方向考虑在内只会略微提高这一点。因此,这种方法在实践中不会特别有效。

    【讨论】:

    • 感谢您回来。我很感激,但我是 AI 的初学者,所以只是在开发启发式函数时寻求初学者帮助。
    • @DanishAli 减少分支因子比开发弱曼哈顿距离的启发式版本更有帮助。
    • @DanishAli 为完整性添加了对类似曼哈顿的启发式的描述。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-30
    相关资源
    最近更新 更多