8 puzzle 算法
算法根据Coursera上的算法课程实现
8 puzzle问题在18世纪70年代由Noyes Palmer提出,并逐渐流行起来。它由8个方块和一共空格组成3X3的格子。8个方块随机放置1-8个数字,目标是移动方块使得8个方块按顺序排放。具体如下:
1 3 1 3 1 2 3 1 2 3 1 2 3
4 2 5 => 4 2 5 => 4 5 => 4 5 => 4 5 6
7 8 6 7 8 6 7 8 6 7 8 6 7 8
initial 1 left 2 up 5 left goal
算法实现
下面具体介绍了Java实现8 puzzle的过程。算法也可以用在4X4的解决中,但是如果问题需要40步以上才能解决时,会有内存溢出的情况,这需要算法进一步优化。
解决问题使用了A*搜索算法,首先定义了一个Board对象,用来描述NxN的一个数据结构。将初始节点放priority queue中,然后得到优先级最高的节点,并计算其相邻的节点,放入priority queue中,持续最高过程,直到节点与目标节点相同为止。
首先定义一个优先级函数:
- Hamming priority function:NxN格子中与预期位置不同的方块的数量。一般来说,具有错误数量方块越少的节点越接近预期的节点。
- Manhattan priority function:所有方块当前与预期位置距离的和。
举例:
8 1 3 1 2 3 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
4 2 4 5 6 ---------------------- ----------------------
7 6 5 7 8 1 1 0 0 1 1 0 1 1 2 0 0 2 2 0 3
initial goal Hamming = 5 + 0 Manhattan = 10 + 0
算法实现:
public Board(int[][] blocks) {
this.blocks = blocks;
}
public int hamming() {
if (hamming >= 0) {
return hamming;
}
hamming = 0;
for (int i = 0; i < blocks.length; i++) {
for (int j = 0; j < blocks.length; j++) {
if (blocks[i][j] != 0)
hamming += i * blocks.length + j + 1 == blocks[i][j] ? 0 : 1;
}
}
return hamming;
}
public