我正在努力寻找一款名为Twiddle的小型益智游戏的最佳解决方案(可以找到游戏的小程序here)。游戏有一个3x3矩阵,数字从1到9.目标是使用最少的移动量使数字按正确的顺序排列。在每次移动中,您可以顺时针或逆时针旋转2x2方格。
即。如果你有这种状态
6 3 9
8 7 5
1 2 4
然后顺时针旋转左上角2x2方格
8 6 9
7 3 5
1 2 4
我正在使用A *搜索找到最佳解决方案。我的f()只是所需的旋转次数。我的启发式功能已经导致最佳解决方案(如果我修改它,看到通知结束)但我不认为它是你能找到的最好的。我当前的启发式获取每个角落,查看角落处的数字,并计算到该数字在解决状态下将具有的位置的曼哈顿距离(这给出了将数字带到此位置所需的旋转次数)并总计所有这些价值观。即你采用上面的例子:
6 3 9
8 7 5
1 2 4
和这个结束状态
1 2 3
4 5 6
7 8 9
然后启发式执行以下操作
6 is currently at index 0 and should by at index 5: 3 rotations needed
9 is currently at index 2 and should by at index 8: 2 rotations needed
1 is currently at index 6 and should by at index 0: 2 rotations needed
4 is currently at index 8 and should by at index 3: 3 rotations needed
h = 3 + 2 + 2 + 3 = 10
此外,如果h为0,但状态未完全排序,则h = 1。
但问题是,您一次旋转4个元素。因此,在极少数情况下,您可以在一次移动中做两次(更多)这些估计的旋转。这意味着这些启发式过高估计了与解决方案的距离。
我目前的解决方法是,简单地排除计算中的一个角落,至少在我的测试用例中解决了这个问题。如果确实解决了这个问题,或者在某些边缘情况下这个启发式算法仍然过高估计,我就没有做过任何研究。
所以我的问题是:你能想出的最佳启发式是什么?
(免责声明:这是一个大学项目,所以这是一个功课。但如果可以提出,我可以自由使用任何资源,所以你可以问你们。我也会相信Stackoverflow帮助我;))
答案 0 :(得分:4)
简单性通常最有效。考虑九个数字(在行 - 第一顺序中)形成一个整数。该解决方案由最小可能的整数i(g)= 123456789表示。因此,我建议以下启发式h(s)= i(s)-i(g)。例如,h(s)= 639875124 - 123456789.
答案 1 :(得分:0)
计算距离时应考虑所有元素,而不仅仅是角元素。想象一下,所有角落元素1,3,7,9都在他们的家中,但所有其他角落元素都没有。
可以认为,在最终状态中作为邻居的那些元素应该在每个步骤中变得更接近,因此相邻距离也可以是启发式的一部分,但可能具有比元素到其最终状态的距离更弱的影响。
答案 2 :(得分:0)
您可以通过考虑所有数字,然后除以4并四舍五入到下一个整数,从您的方法中获得可接受的(即,不要高估)启发式。
要改进启发式,您可以查看数字对。如果是在左上角,数字1和2被交换,你需要至少3次旋转来固定它们,这比单独考虑它们的1 + 1更好。最后,你仍需要除以4.你可以任意配对数字,甚至可以尝试所有对,并找到最好的分组。