答案 0 :(得分:4)
学习Wikipedia可能比研究实际的源代码更好。 A *在那里写得很清楚。但这感觉就像作弊,不是吗?
作为所有好主意,A *在回顾展中实际上非常明显。尝试完成它很有趣,并且在此过程中有一些很好的见解。这是你如何做到的:
编写蛮力解算器。您需要在更高级版本中编写的大部分内容:游戏状态以及从一个州到另一个州的描述。您最终还会删除重复的状态。你应该有一个类型的队列来考虑状态,你已经完成的一组状态,以及保存迄今为止找到的最佳解决方案的结构。还有一种方法,它从队列中获取状态并生成状态的“邻居”状态(可以从中获取)。这是经典AI算法的基本结构。请注意,您在技术上“生成”或“探索”了一个巨大的图表。
之后,添加一个简单的修剪算法:如果状态只剩下一个颜色的块,则无需进一步考虑。看看你是否可以提出其他修剪算法(即将状态标记为“无法解决”的算法)。一个好的修剪算法将消除许多无意义的状态,从而证明运行修剪本身所需的时间。
然后,引入一个启发式分数:用一个数字对每个州进行排名,该数字告诉你状态看起来“好” - 关于它将需要多少解决。将您的队列设为priority queue。这将允许您首先考虑“最佳外观”状态,因此程序应该更快地提出 a 解决方案。但是,找到的第一个解决方案实际上可能并不是最好的,所以为了确保找到最好的解决方案,你仍然需要运行整个程序。
存储您到达每个州的最低费用(移动次数)。如果找到更好的路径,请记得更新它。首先考虑成本和启发式得分最低的州;那些更有可能带来更好的解决方案。
这是A *。您需要修改启发式函数,使其不会高估与目标的距离,即它可能低于您实际需要的移动次数,但不会更高。然后,请注意,如果您找到了解决方案,其启发式分数将为0.并且,任何其成本和启发式总和超过解决方案成本的状态都无法带来更好的解决方案。所以,你可以修剪那个状态。但是由于你按顺序处理状态,一旦你达到了这个阈值,你就可以停下来返回,因为队列中的所有其他状态也会被修剪。
现在剩下的就是完善你的启发式:它永远不会高估,但更好的估计它会减少A *所需的时间。启发式越好,结果越好。注意启发式不需要花费太多时间来完成 - 你不会想要通过蛮力产生解决方案,即使它会给出完美答案:)
维基百科有更多的讨论和可能的改进,如果你做到这一点。但是,此时您可以做出的最佳改进可能来自改进启发式功能。
答案 1 :(得分:1)
也许将其转换为经典规划问题(使用PDDL语法)。然后你可以尝试一些免费提供的规划师。
E.g。试试Fast Forward。