一, 导语
拼图游戏很适合休闲放松的时候玩,所以在上大学的一段时间里,我比较喜欢玩,用来打发无聊的时光。
恰巧2016年李世石与阿尔法狗对弈,虽然我不懂围棋,但也跟着围观了每场比赛。当时我想既然下围棋能够用算法完成,那自动复原拼图应该是更简单的一件事,一定会有算法。人工智能课上老师也讲过复原拼图的 \(A^*\) 算法,上网查资料拼图的复原也大都用 \(A^*\) 算法。不过对于复原拼图来讲, \(A^*\) 算法和瞎蒙的差别不大,如果M和N的值较小 \(A^*\) 可以适用,当M和N过大时由于搜索空间变得太大就不可行了。那么有没有一种更明确的算法,可以计算出复原拼图的路径呢?
二, 基本概念
约定1 :M*N拼图是由m行n列个图块构成的拼图。
约定2:用大写字母P表示拼图, \(P_i\) (i=1,2,3……n)表示拼图所处的某一状态, \(P_e\) 表示拼图的原始状态或复原状态。
定义1:复原拼图,可以表示为
\(P_i \overset{f}{\Rightarrow} P_e \) ,
即算法f作用到 \(P_i\) 上,使其回复到 \(P_e\) 状态。
定义2:拼图从 \(P_i\) 到 \(P_{i+1}\) 的状态变换为 \(φ·P_i=P_{i+1}\) ,简写为 \(φP_i=P_(i+1)\) ,即φ作用于状态 \(P_i\) 使其变化为状态 \(P_{i+1}\) 。
约定3:M*N拼图,我们用数字1,2,3……,mn-1作为图块的编号,用mn作为缺失图块的编号。用数字1,2,3……,mn表示位置的编号,位置的编号为从左至右,从上至下,依次递增,即左上角位置编号为1,右下角位置编号为mn。
约定4:图块 \(a_j\) 直接称为 \(a_j\) 。
以3*3拼图为例,它的位置编号如右图:在 \(P_e\) 状态下每个图块所在的位置的编号等于图块的编号。
定义3:设mn=o,拼图在状态 \(P_i\) 的具体表示为 \(P_i=\begin{pmatrix} 1 & 2 & 3 & \cdots & j & \cdots & k & \cdots & o\\ a_1 & a_2 & a_3 & \cdots & a_j & \cdots & a_k & \cdots & a_o \end{pmatrix}\)
,数列 \(α_1,α_2,α_3,……,α_o\) 表示图块编号,数列 \(1,2,3,……,o\) 表示位置,如果 \(α_j=o\) ,代表 \(a_j\) 为缺失的那个图块。
定义4:设 \(a_i 所在的位置编号是C_{α_i},表示为\) \(a_j (C_{a_j })\)
或 \(a_j (\frac{C_{a_j}-C_{a_j} (modn)}{n},C_{a_j} (modn)),\frac{C_{a_j}-C_{a_j} (modn)}{n}\) 为行号 \(C_{a_j } (modn)\) 为列号。
拼图这样的表示方法和置换群的表示方法相同,事实上根据群的定义,拼图的所有状态构成群,可以吧拼图状态的变化看成置换群运算。
三, 等价性证明
本节将证明拼图状态变化与置换运算的等价,这是整个算法的理论基础。
证明:设 \(P_i=\begin{pmatrix} 1 & 2 & 3 & \cdots & j & \cdots & k & \cdots & o\\ a_1 & a_2 & a_3 & \cdots & a_j & \cdots & a_k & \cdots