跳到正文
格致开物MATHWIKI

拉丁方

内容维护:格致开物 · 编写与核验 · 修订记录 · 纠错

拉丁方(Latin square)是一个 n×n 方阵,使用 n 种符号,并使每种符号在每行、每列中都恰好出现一次。n 称为阶数。它约束的是行列中的出现次数,符号可以是数字、字母或处理方案,不要求作普通数值运算。

例如,三种处理编号为零、一、二,安排在三个位置与三个时段的交叉表中,可以使用 L=(012120201). 每个位置一行、每个时段一列,每种处理在每个位置及每个时段各出现一次。这样的均衡安排有助于把两个分组因素与处理区分,但它不自动消除所有交互作用,也不代替随机化和数据分析。

定义与循环构造

设符号集合为 S、|S|=n≥1。方阵 L=(Lij) 为拉丁方,当且仅当对每个固定的行 i,映射 j↦Lij 是从列指标到 S 的双射;对每个固定的列 j,映射 i↦Lij 也为双射。

任何正整数阶数都存在拉丁方。取行列与符号都用 0,…,n−1 标号,定义 Lij=i+j(modn). 证明。 在同一行内,若 i+j1≡i+j2(modn),减去 i 得 j1≡j2;指标都在 0,…,n−1 内,因而相等。该行 n 个值互异,正好穷尽全部符号。固定列时同理。这个证明只使用模加法,不需要 n 为素数。

三阶循环拉丁方的每行由上一行循环平移,三种符号用数字和不同颜色同时标识
每行与每列都包含 0、1、2 各一次。相邻行循环平移,是这一种构造的特点,不是所有拉丁方的额外定义。

单独检查各行还不够。例如 (012120021) 每行仍是三种符号的排列,但第一列出现两个零,第二列也出现重复,故不是拉丁方。定义必须同时控制两种方向。

行、列和符号的重新标号

对一个拉丁方任意交换行、任意交换列,或对全表统一重新命名符号,仍得到拉丁方。交换整行不改变任何行内的符号集合,也只是重新排列各列的元素;另两种操作可用同样方式核对。这些操作称为拉丁方的同位变换的一部分,常用于把第一行和第一列整理成指定顺序。

重新标号必须一致地作用到全表。同一个符号若在不同格里被改成不同的新符号,就可能破坏列约束。不同拉丁方也未必都能通过这三类操作相互转换;循环加法表提供了存在性构造,而非所有拉丁方的分类。

两张表的正交性

两张同阶拉丁方 L,M 称为正交,若把对应格的符号配成有序对 (Lij,Mij) 后,全部 n2 种有序对恰出现一次。

在三阶例子中,取 Mij=i+2j(mod3),M=(021102210). 固定行时,乘二是模三符号的一个排列;固定列时,随 i 增加也是排列,因此 M 是拉丁方。进一步,若某格的有序对为 (a,b),方程 i+j≡a,i+2j≡b(mod3) 相减得 j≡b−a,再得 i≡2a−b。行列被唯一确定,所以每个有序对恰出现一次,证明两方正交。[1]

三阶拉丁方L与M叠加后九个格子分别包含九种不同有序对
例如有序对 (2,1) 解得 j=2、i=0,正好对应第一行第三列。正交要求整张表中所有有序对互异,比每张表分别满足行列约束更强。

变式。 对四阶尝试 Mij=i+2j(mod4) 会失败:第一行是 0,2,0,2,已经不是拉丁方。失败原因是二在模四下不可逆。它否定的是这个特定公式,不能推出“四阶没有正交拉丁方”;其他构造需要另行分析。

在素数 p 下,公式 Lij(a)=i+aj(modp) 对每个非零 a 都给出拉丁方。若 a≠b,两个输出相减得到 (a−b)j;非零数在模素数中可逆,所以两个输出唯一确定格子。这样得到 p−1 张两两正交的拉丁方。它是一个明确的素数阶构造,不应把同样的除法步骤直接搬到合数模数中。

生成与检验

以下代码使用符号 0,…,n−1,生成循环拉丁方,并独立按定义检查行、列的符号集合。函数不修改输入矩阵。

Python 3
def cyclic_latin(order):
    if type(order) is not int or order < 1:
        raise ValueError("order must be a positive integer")
    return [[(row + column) % order for column in range(order)]
            for row in range(order)]


def is_latin(square):
    rows = [tuple(row) for row in square]
    n = len(rows)
    if n == 0 or any(len(row) != n for row in rows):
        return False
    if any(type(x) is not int or not 0 <= x < n
           for row in rows for x in row):
        return False
    symbols = set(range(n))
    return (all(set(row) == symbols for row in rows)
            and all({rows[i][j] for i in range(n)} == symbols
                    for j in range(n)))


print(cyclic_latin(3))
print(is_latin(cyclic_latin(3)))
print(is_latin([[0, 1, 2], [1, 2, 0], [0, 2, 1]]))
# [[0, 1, 2], [1, 2, 0], [2, 0, 1]]
# True
# False

每行和每列均被完整检查;一个含 n 个合法符号的行集合等于全部符号,当且仅当每种恰出现一次。因而代码不是只比较行列和,而是直接检查定义。生成和检验均需 O(n2) 次基本操作;生成结果或检验时复制的输入占 O(n2) 空间。只检查和为 n(n−1)/2 不够,因为重复符号也可能凑出相同的和。

试验安排的数学含义

把行看成地点、列看成时段、格内符号看成处理,拉丁方保证各处理在每一地点、每一时段都出现一次。这是一种精确的组合均衡。若进一步建立“观测值等于总体均值、行效应、列效应、处理效应与误差之和”的加性统计模型,仍须说明误差与交互作用的假设,并合理随机化地点、时段和处理标号。

数独的完成盘还要求每个指定小宫格中符号不重复,所以它是在拉丁方约束上增加了限制。一般拉丁方不必满足宫格条件;相反,满足全部数独规则的盘面一定是相应阶数的拉丁方。

相关条目

  • 正交表:把行、列与处理同时当作因素,描述组合均衡。
  • 覆盖数组:以“至少出现一次”代替精确均衡的组合覆盖。

参考资料

  1. ↑ Andries E. Brouwer:Orthogonal Arrays,Eindhoven University of Technology,关于强度二、指数一的正交表与拉丁方、互相正交拉丁方的对应。该页把试验放在列,本文按通常的拉丁方行列布局解释,并在正交表中改用试验为行的约定。访问日期:2026年10月25日。