线性代数中排列的逆序数在实际开发中的应用--js进行拼图游戏有解性判断
文中拼图游戏玩法为:右下角一块是空白块,其他为随机打乱的碎图块,通过交换位置得到正确图案的拼图玩法。
这类拼图游戏初始碎图块的生成步骤比较简单:
第一步:将一个完整的图片切成n*n的碎图,右下角最后一块,替换为空白块。
第二步:将除空白块以外的碎图随机打乱位置。
有些人到了这一步,就认为初始碎图块生成完成了,但其实是有问题的,第二步可能会导致拼图有50%的概率无法拼好,即生成了无解拼图。
什么是无解拼图,例如:
0 1 2
3 4 5
7 6
这样拼到最后相邻两个碎图位置互换才能完成的拼图,就是无解拼图。
这里结合线性代数中的知识解释一下为什么这是无解拼图:
首先有定理:交换排列的任意两元素,排列的奇偶性必定发生改变;
然后我们给拼图的未打乱时的碎图编个号:
0 1 2
3 4 5
6 7
可以得到完成拼图时的排列为:01234567,其中逆序数为0,是一个偶排列。
由于拼图玩法只能通过碎图与空白块来交换位置,并且开始开始时和结束时空白块的位置保持不变。如果完成了拼图,可以分析出:
空白块移动的次数一定是偶数次,序列交换任意两元素的次数为偶数次。
结合上文,可以得出:
若要拼图游戏一定可以完成,初始碎图组成的排列必须为偶排列。
所以只要写一个js方法判断,计算碎图组成的排列的逆序数就可以判断一个拼图游戏是否为无解拼图了,最后是一个简单的计算逆序数的js:
function getInversionNum(arr){
var count = 0
for(var i=0;i<arr.length;i++){
for(var j=i+1;j<arr.length;j++){
if(arr[i]>arr[j])count++
}
}
return count;
}