算法:拉丁方阵(Latin Square)

  拉丁方阵(英语:Latin square)是一种 n × n方阵,在这种 n × n 的方阵里,恰有 n 种不同的元素,每一种不同的元素在同一行或同一列里只出现一次。以下是两个拉丁方阵举例:

  拉丁方阵有此名称是因为瑞士数学家物理学家欧拉使用拉丁字母来做为拉丁方阵里的元素的符号。

  算法步骤:

  • 在第一行中,数字从 1 到 n 连续存储。
  • 第二行,数字向右移动一列。即 1 现在存储在第二列,依此类推。
  • 在第三行中,数字向右移动两列。即 1 现在存储在第三列,依此类推。
  • 对于其余的行,我们将以相同的方式继续。
 1 package algorithm;
 2 
 3 /**
 4  * 拉丁方阵
 5  */
 6 public class LatinSquare {
 7     /**
 8      * 打印拉丁方阵
 9      * 
10      * @param n 方阵边长
11      */
12     private static void printLatin(int n) {
13         int k = n + 1;
14 
15         // row
16         for (int i = 1; i <= n; i++) {
17             int temp = k;
18 
19             while (temp <= n) {
20                 System.out.print(temp + " ");
21                 temp++;
22             }
23 
24             // 每行后面补 1...k-1
25             for (int j = 1; j < k; j++) {
26                 System.out.print(j + " ");
27             }
28 
29             k--;
30             System.out.println();
31         }
32     }
33 
34     public static void main(String[] args) {
35         int n = 5;
36         printLatin(n);
37     }
38 }

关于拉丁方阵的一些内容:

拉丁方阵的正交

  设有两个阶数相同(为)的拉丁方阵{\displaystyle A_{1}=(a_{i,j}^{(1)})_{n\times n},A_{2}=(a_{i,j}^{(2)})_{n\times n}},其中将所有放置位置相同的元素组合成一个元组,组合成一个新的矩阵{\displaystyle ((a_{i,j}^{(1)},a_{i,j}^{(2)}))_{n\times n}}。 当这个新的矩阵{\displaystyle ((a_{i,j}^{(1)},a_{i,j}^{(2)}))_{n\times n}}中每一个元素互不相同时,拉丁方阵A_{1}和 A_{2}是互相正交的。 此时,A_{1}A_{2}即为一对正交拉丁方。 而在阶数固定的情况下,所有两两正交的拉丁方所成的集合称为正交拉丁方族

  如当 n=3 时,存在两个正交的拉丁方。{\displaystyle {\begin{bmatrix}1&2&3\\2&3&1\\3&1&2\\\end{bmatrix}}} {\displaystyle {\begin{bmatrix}1&2&3\\3&1&2\\2&3&1\\\end{bmatrix}}} 

 

拉丁方阵的数量

  可能有不止一种可能的拉丁方形。

  目前,没有公式可以计算 n × n 的拉丁方阵的数量,而当前最精确的公式在当 n 很大时,拉丁方阵的数量的最精确的估计值,其上下界也相差很远。 具体估计公式为: {\displaystyle \prod _{k=1}^{n}(k!)^{n/k}\geq L_{n}\geq {\frac {(n!)^{2n}}{n^{n^{2}}}}}

posted @ 2019-12-28 15:19  賣贾笔的小男孩  阅读(4058)  评论(0编辑  收藏  举报