前一阵人工智能课需要写一个八数码的题,其中用到了康托展开。
但当时是直接使用的公式,并没有仔细阅读具体的原理。
所以,今天整理一下。
简介
康托展开是全排列到自然数的双射,常用于对全排列的哈希。
康托展开实质是表示的是当前排列在全排列中的位置。
公式
n个数字排列的康托展开公式:
其中,ai表示第i位数字在当前集合是第ai小的数字。
逆过程
初始化集合Cn为n个数字的全集,Xn=X。
Xi mod (i-1)!,商为qi,余数为ri;
则ai为当前集合中第qi小的数(第0小的数为最小数);
从集合中删除ai,得到集合C(i-1);
X(i-1)=ri;
重复以上过程,即可求出X对应排列。
举例
n=9;
康托展开
3 5 7 4 1 2 9 6 8 展开为 X=2*8!+3*7!+4*6!+2*5!+0*4!+0*3!+2*2!+0*1!+0*0!=98884;
初始集合为{1,2,3,4,5,6,7,8,9},3是第2小的数字,所以a9=2;然后从集合中删除3。
当前集合{1,2,4,5,6,7,8,9},5是第3小的数字,所以a8=3;然后从集合中删除5。
……
康托展开逆过程
98884除以8!,商2,余数18240;当前集合{1,2,3,4,5,6,7,8,9}第2小的数为3,所以x9=3。
18240除以7!,商3,余数3120;当前集合{1,2,4,5,6,7,8,9}第3小的数为5,所以x8=5。
……