问题:
拉丁方阵(英语:Latin square)是一种 \(n × n\) 的方阵,在这种 $n × n \(的方阵里,恰有\) n $种不同的元素,每一种不同的元素在同一行或同一列里只出现一次。
\[ \begin{bmatrix} 1&2&3 \\\ 2&3&1 \\\ 3&1&2 \end{bmatrix} \begin{bmatrix}a&b&d&c \\\ b&c&a&d \\\ c&d&b&a \\\ d&a&c&b \end{bmatrix} \]
目前,没有公式可以计算 \(n × n\) 的拉丁方阵的数量。
标准型
当一个拉丁方阵的第一行与第一列的元素按顺序排列时,此为这个拉丁方阵的标准型。
下图即为一种标准型:
\(\left[ \begin{array}{cccc} 1 & 2 & 3 & 4 \\\ 2 & 1 & 4 & 3 \\\ 3 & 4 & 1 & 2 \\\ 4 & 3 & 2 & 1 \end{array} \right]\)
同型类别
许多对于拉丁方阵的运算都会产生新的拉丁方阵。例如说,交换拉丁方阵里的行、交换拉丁方阵里的列、或是交换拉丁方阵里的元素的符号,都会得到一个新的拉丁方阵。交换拉丁方阵里的行、交换拉丁方阵里的列、或是交换拉丁方阵里的元素的符号所得的新的拉丁方阵与原来的拉丁方阵称为同型(isotopic)。同型(isotopism)是一个等价关系,因此所有的拉丁方阵所成的集合可以分成同型类别(isotopic class)的子集合,同型的拉丁方阵属于同一个同型类别,而不属于同一个同型类别的拉丁方阵则不同型。
同型的计算
摘自爱问知识人
第一步
先设定一种最简单排法,假定1在第1排,第1列
第一排,\(1~n,\)
第二排,\(2~n,1,\)
第三排,\(3~n,1,2,\)
第四排,\(4~n,1,2,3,\)
第\(n-1\)排,\(n-1,n,1~(n-2),\)
第\(n\)排,\(n,1~(n-1),\)
第二步
把第\(2\)到第\(n\)排(整排)任意换位置重新排列,总满足要求,共有\((n-1)!\)种排法,
第三步
把第\(2\)到第\(n\)列(整列)任意换位置重新排列,总满足要求,共有\((n-1)!\)种排法,
第四步
把第\(1\)排的\(1\)分别可以换到第\(2~n\)列,算上前面第\(1\)列,共有\(n\)种排法,
所以,共有\(n\times (n-1)!\times (n-1)!=n!\times (n-1)!\)种排法。
end
即对于一个已知的一个拉丁方阵,同型的有\(n!\times (n-1)!\)个
所谓的"已知解行列交换法"重复原因
摘自知乎
假设你先随便弄出一套满足的情况,然后你可以把行打乱随便排序,\(4!=24\),同理列也行,\(4!=24\)
两种情况合起来,\(24*24=576\)。不妨称上面的的解法为“已知解行列交换法”。
(1)对\(n\times n\)的表格,行列交换法的结果是\(s=n!\times n!\)。对于\(2\times 2\)和\(3\times 3\)的表格时 \(s\)分别为\(4、36\),但实际上只有\(2、12\)种可能。于是最初猜测行列交换法会存在重复。
(2)为了验证行列交换法是否有重复解,我用程序对\(4\times 4\)的表格进行行列交换,去重后是\(144\)种,确实存在重复。
(3)那么正确结果是\(144\)吗? 接着用穷举法,列出所有解进行筛选,去重后是\(576\)种,可见,对已知解行列交换,无法涵盖所有的解。以上几点证明行列交换法的思路是错误的(尽管它在\(4\times 4\)的时候得到了正确的结果)。
来说说自己的:
可先给行列标号:
若第一行为\(1,2,3,4……n\)。
则列交换后可将第二行变得与第一行一致,且其余的新的每行都与之前某一行一致,则再在行交换后可得到与原来一致的方阵。共有\(n\)行,则有\(n\)种重复情况。
所以同样得到:对于一个已知的一个拉丁方阵,同型的有\(\frac{(n!^2)}{n}=n!\times(n-1)!\)个
拿\(4\times 4\)做例子
比如已知一个拉丁方阵:
\(\begin{array} & & & 1 & 2 & 3 & 4 \end{array}\\\ \begin{array}{} 1 \\ 2 \\ 3 \\ 4 \end{array} \begin{bmatrix}{} 1 & 2 & 3 & 4 \\\ 2 & 3 & 4 & 1 \\\ 3 & 4 & 1 & 2 \\\ 4 & 1 & 2 & 3 \end{bmatrix}\)
先进行列交换
后:
$ \begin{array} & & & 4 & 1 & 2 & 3 \end{array}\ \begin{array}{} 1 \ 2 \ 3 \ 4 \end{array} \begin{bmatrix}{} 4 & 1 & 2 & 3 \ 1 & 2 & 3 & 4 \ 2 & 3 & 4 & 1 \ 3 & 4 & 1 & 2 \end{bmatrix}$
再进行行交换
后:
$ \begin{array} & & & 4 & 1 & 2 & 3 \end{array}\ \begin{array}{} 2 \ 3 \ 4 \ 1 \end{array} \begin{bmatrix}{} 1 & 2 & 3 & 4 \ 2 & 3 & 4 & 1 \ 3 & 4 & 1 & 2 \ 4 & 1 & 2 & 3 \end{bmatrix}$
行列标号的排列
由\(1,2,3,4/1,2,3,4\)变为\(2,3,4,1/4,1,2,3\),但拉丁方阵未变
。
对于一个能将第\(i\)行变得与第一行一致的列标号的排列
,一定能找到唯一一个
能使拉丁方阵不变的行标号的排列。
如对上述行列标号的排列
,得到的拉丁方阵相同的排列
有\(4\)种。
\(1,2,3,4/1,2,3,4\)
\(2,3,4,1/4,1,2,3\)
\(3,4,1,2/3,4,1,2\)
\(4,1,2,3/2,3,4,1\)
标准型的计算
好像国际上也只能暴力找,最多到\(n=11\)。
可以看看OEIS(整数数列线上大全)的A000315
上一发自己写的代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#define fr(x) freopen(#x ".in","r",stdin);freopen(#x ".out","w",stdout)
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int MaxL=20,Max=1e5;
typedef long long ll;
int M[Max][MaxL];
int *m[MaxL];
int n,tot=0,numtot=0;
void dfs(int,int);
bool check(int);
void make();
int main()
{
// fr(latin);
int T[Max];
scanf("%d",&n);
for(int i=0;i<n;i++) T[i]=i+1;
do
{
++numtot;
for(int j=0;j<n;j++) M[numtot][j]=T[j];
}while(next_permutation(T,T+n));
m[1]=&M[1][0];
dfs(2,1);
printf("%d\n",tot);
fprintf(stderr,"%.3f s\n",clock()*1.0/CLOCKS_PER_SEC);
return 0;
}
void dfs(int line,int num)
{
if(line>n) return ++tot,make(),void();
if(num>numtot) return;
for(int i=num;i<=numtot;i++)
{
m[line]=&M[i][0];
if(check(line)) dfs(line+1,i+1);
}
// while(!check(line)) m[line]=&M[++num][0];
return;
}
bool check(int line)
{
for(int i=line-1;i;i--)
{
for(int j=0;j<n;j++)
if(!((*(m[line]+j))^(*(m[i]+j)))) return false;
}
return true;
}
void make()
{
for(int i=1;i<=n;i++)
{
for(int j=0;j<n;j++) printf("%d ",(*(m[i]+j)));
puts("");
}
puts("");
}
所有的拉丁方阵数量
为什么之前要说标准型
?
因为对于一个\(n\)阶拉丁方阵,不同的标准型之间不是同型
,换句话说,只要知道\(n\)阶拉丁方阵的标准型个数,再乘上同型的个数,就是所有\(n\)阶拉丁方阵数量。
但国际上也只能暴力找,最多到\(n=11\)。
PS:
用我写的程序暴力找\(n=7\)时的标准型个数,用时:
10001.097 s
约合\(2h50min\)(吓~~)
高中数学
在\(4×4\)的方格中,每个格子都填入\(1、2、3、4\)四个数字之一,要求每行、每列都没有重复数字,不同的填法共有( )
A.\(24\)种 B.\(144\)种 C.\(432\)种 D.\(576\)种
如果你已经知道拉丁方阵,并知道\(n=4\)时标准型的个数为\(4\)时,恭喜你,这道题秒杀~~
那如果不知道呢……
有比较常规的方法。
begin
我们可以一行一行的确定。
第一行没有限制,共\(4!=24\)种。
假设取出一组\([a,b,c,d]\)定为第一行。
根据错排问题的结论,第二行有\(9\)种。
那第三行呢?
我们发现事情并没有那么简单,在第二行不同的情况下,第三行可能有\(2\)种或\(4\)种……
怎么办?
只有分类讨论,看看是什么导致了\(2\)种或\(4\)种两种情况的产生。
第一行:\([a,b,c,d]\)
要构造出满足条件的第二行,第一个肯定不是\(a\),可以是\(b,c,d\)中的一种,假定选\(b\),那第二个呢?
可以是\(a,c,d\)中的一种,所以,区别开始了……
一、选\(a\)
如果这么选,那么这行就确定了:\([b,a,d,c]\)
观察一下特点:
\([a,b,c,d]\\ [b,a,d,c]\)
发现其实就是\(a,b\)交换,\(c,d\)交换。
把变换画成环就是这样: