拼图问题又叫N数码问题。这个问题比较简单,基本上有一个人研究透彻之后就再也没有研究价值了。
2010年《计算机应用软件》上发表的一篇论文《N数码问题直接解与优化问题研究》对N数码问题的可解性和直接解法进行了透彻的研究。
此[repo](https://github.com/weiyinfu/pintu)提供了一个拼图自动求解算法(非最优解)。
一.拼图问题定义
给定一个m行n列的平面方格图(m!=1&&n!=1),只有一个空位,其余每个方格内为1~(m*n-1)的数字.可以将空格与其上下左右相邻方格内的卡片交换位置.目标就是从左到右,从上到下依次排成从1到(m*n-1)的阵列,空位在最后一格内.
二.定义:拼图某状态的逆序数
从左到右,从上到下,各个格点内的数字形成一个序列,这个序列的逆序数就是当前状态的逆序数.对于任意一个拼图,目标状态的逆序数一定是0,因为肯定是1,2,3....这样排列的.
三.操作对拼图逆序数的影响
对于一个状态,可以将空格与其上下左右4个位置的卡片交换位置.左右交换不影响状态的逆序数,这是显然易见的.
上下交换,相当于多次交换.当列数为奇数,上下交换相当于交换偶数次,奇偶性不变;当列数为偶数,上下交换相当于交换奇数次,奇偶性变化.
例如,状态[1,2,3;4,_,6;5,7,8]的逆序列为12346578.将空格与空格下方的7交换位置,变成12347658,相当于先是7与5换,然后再跟6换,交换了偶数次,逆序数不变.
所以,操作是否影响奇偶性取决于列数的奇偶性.
四.空格状态的奇偶性
如果空格所在行与目标行的行距为偶数,则称空格状态为偶数性;若为奇数,则称空格状态为奇数性.
五.拼图问题可解的充要条件
知道目标状态,知道操作过程,就足以攻克一切问题.
操作与奇偶性的关系有两种:左右交换始终不影响奇偶性.(1)列数为奇数,上下交换不影响奇偶性;(2)列数为偶数,上下交换影响奇偶性.
关键在于找到操作中的守恒量,虽然每一个操作都会产生下一个状态,但是这个过程中有守恒量:
如果列数为奇数,状态逆序数的奇偶性守恒.
如果列数为偶数,状态逆序数的奇偶性^空位状态的奇偶性守恒.其中^表示异或运算.
于是结论是,当列数为奇数时,一切操作不影响奇偶性,当前状态逆序数为偶数 等价于 拼图有解.
当列数为偶数时,上下交换影响奇偶性,只要当前状态逆序数奇偶性^当前空格状态的奇偶性=偶数 等价于 拼图有解.其中^符号表示异或运算.
一言以蔽之,拼图有解定理就是:当前状态守恒量的值为偶数.
六.证明:拼图有解=>当前状态守恒量的值为偶数
对于列数为奇数的拼图,操作中满足状态逆序数奇偶性不变,所以只有当前状态与目标状态奇偶性一致才有可能有解.
对于列数为偶数的拼图,操作中满足状态逆序数奇偶性^当前空格状态奇偶性不变,所以只有当前状态的逆序数奇偶性^当前空格状态奇偶性与目标状态一致才有可能有解.
这个问题蕴含的道理十分丰富:
(1)分析变化的事物要找到变化中的守恒量.
(2)要注重开头和结尾,不要在意中间的过程.
七.证明:拼图守恒量的值与目标状态相同=>拼图有解
把拼图分成四个部分:左上角的m-2行n-2列、下面的2行n-2列、右面的m-2行2列、右下角的2行2列,这四部分分别记作A、B、C、D。完成顺序为A、B、C、D,逐块拼成。
A部分很容易拼成,不必赘言。
B、C两部分同构,只需要讨论其中一个。
D部分不用说了,2行2列太简单了。
下面重点讨论B部分。
第一步,先处理好1位置;第二步,把1上面的邻居挪到4位置;第三步,把空格挪到5。这三步都是轻而易举可以完成的。
至此就可以应用一个固定的“公式”。让1迎接4位置回家。
上述证明的思想就是,构造几个操作,某些区块它们能够不影响别人,而把自己调整成正确的状态.
上面是以行少列多为例,对于行多列少的情况显然也成立.
八.关于拼图问题的其他结论
(1)将空格移动到右下角后拼图状态逆序数奇偶性为偶数<=>拼图有解.
(2)交换任意两个非空格块(可以不相邻),有解的会变成无解,无解的会变成有解.
(3)将空格移动到右下角后,若有偶数对方块正好颠倒,问题有解;若有奇数对方块颠倒,问题无解.
(4)拼图的状态构成一张图,边就是操作.拼图的结点有两种(有解和无解),有解的结点必然能够到达目标结点,目标结点也能到达它们,所以有解结点集是连通的,无解结点集其实也是连通的,此图有两个连通分量.但不知道如何证明.
九.应用
生成拼图问题时,关键是要保证拼图有解.一种方法是先生成目标状态,一番随机操作打乱之.这种方法在拼图行数列数较小时比较适用,一旦拼图规模变大,随机操作的次数不够就容易生成很简单的拼图.
另一种方法就是利用拼图有解的充要条件.随机生成拼图序列,如3*3的拼图随机生成为312450678,其中0表示空位.然后判断它是否有解,如果无解交换两个非空方格内的数字,如果有解,就更好了.这种方法对拼图的打乱强度比较大,很容易生成杂乱无章的拼图.
十.以2行4列拼图为例检验一下结论