为什么我的 A* 算法在拥有正确启发式函数的情况下仍然扩展了过多的节点?

我正在做一个作业,需要使用 A* 算法来解决一个 15 拼图 (用 C 语言实现)。

启发式函数是 曼哈顿距离 (也称为出租车距离)。

我们得到了一个输入/输出示例,其中拼图在 22 步内解决,并扩展了 395 个节点(拼图状态)(即,我们必须查看 395 个节点的子节点)。

我所说的“正确”启发式函数是指我的函数与生成示例输出时使用的函数相同,并且产生正确的距离。

问题是 我的解决方案扩展了超过 400 个节点才能找到解决方案(它是最优的 22 步,但与示例不同)。

我注意到 数字会随着我生成子节点的顺序而变化(向上、左、下、右移动空格瓷砖,或者其他方向)。

总共有 24 种方法可以向上、向下、向左和向右移动空格瓷砖以生成子节点,我尝试了所有这些方法,但没有一种方法扩展 395 个节点。

为什么会这样?

术语:

  • 节点:每个节点都是 15 拼图的一个配置
  • 子节点:可以通过从当前节点向上、向下、向左或向右移动空格瓷砖来实现的配置

PS:我在开放列表中使用二叉堆,如果这很重要的话

谢谢


回答:

嗯… 在理想情况下,A* 算法不依赖于您生成子节点的顺序。不幸的是,如果在“队列”中有两个或更多具有相同距离加成本启发式值的节点,该算法可能会“随机”选择其中一个节点并找到不同的解决方案(并探索不同的搜索路径)。

我认为您可以尝试:

  • 检查您的距离加成本启发式函数。(每个动作成本为 1 吗?您是否正确地计算了每个方块到其正确位置的距离之和?)
  • 检查您的堆。它返回正确的节点吗?在同一步骤中,您可以拥有多少个具有相同启发式值的节点?

根据这些信息,我只能告诉您这些了。:)

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注