问题描述
八数码问题。在3*3的方格盘上,放有八个数码,剩下第九个为空,每一个空格上下左右的数码可移至空格。问题给定初始位置和目标位置,要求通过一系列的数码移动,将初始位置转换为目标位置。求出从初始位置移动到目标位置的步骤,同时还给出了最短移动路径。
算法原理
首先将空格设为数字0,将3*3方格盘中的数字转换为一个字符串,如‘283104765’,将空格上下左右的数码移动看作空格的移动,这样每个状态最多可对应四个子状态。
采用BFS遍历的方式寻找最优路径,首先定义一个State对象来存放八数码的每一个状态信息,其中包括节点对应的状态字符串值,节点在BFS遍历树中的深度,以及父节点信息,定义order数组存放BFS时节点的访问次序,定义visited数组存放已经访问过的节点状态。
利用队列实现遍历,具体步骤如下:
- 首先判断初始状态与目标状态的逆序数是否同为奇数或者同为偶数。
- 若奇偶性相同,则目标状态可达,若奇偶性不同,则目标状态不可达,结束。
- 当目标状态可达时,将初始状态压入队列中。
- 判断队列是否为空,若为空,退出循环,打印移动步骤,结束。
- 取出队头元素判断是否与目标状态一致。
- 若一致,则退出循环,输出移动步骤,程序结束。
- 若不一致,则分别判断空格向左、向上、向下以及向右能否移动进行BFS遍历。空格位置约束条件映射到字符串分别为
,判断子状态是否已经遍历过,若无,则将该子状态压入队列,将该状态放入visited数组。
- 跳转到步骤四。