著名的九宫格问题是要找到一种方法,在一个n×n的棋盘上摆放九只皇后,使其不攻击任何其他皇后。也就是说,没有两个皇后可以在同一行,同一列,或同一对角线上。这里有一个解决方案的例子。

Costas数组
在这篇文章中,我们将研究一个类似的问题,削弱一个要求并增加一个要求。首先,我们要去掉没有两个棋子可以在同一对角线上的要求。这就把n个皇后的问题变成了n个车的问题,因为车不能在对角线上移动。
接下来,想象一下从每个车到每个其他车的硬线。我们将要求没有两根线具有相同的长度和运行方向。用更多的数学术语来说,我们要求所有车之间的位移矢量是唯一的。
这个问题的解决方案被称为科斯塔斯阵列。 1965年,J.P.Costas发明了现在被称为Costas阵列的东西,以解决雷达信号处理中的一个问题。
为什么我们称一个解决方案为科斯塔斯阵列而不是科斯塔斯矩阵?因为一个矩阵解决方案可以通过记录每一列所占单元的行号来描述。例如,我们可以把上面的八个皇后的解决方案描述为
(2, 4, 6, 8, 3, 1, 7, 5).
在这里,我是自下而上给行编号,就像第一象限的点一样,而不是像矩阵那样从上到下。
请注意,上述八个皇后问题的解决方案不是科斯塔斯阵列,因为皇后之间的一些位移向量是相同的。例如,如果我们从左到右给皇后编号,第一和第二只皇后之间的位移向量与第二和第三只皇后之间的位移向量相同。
Costas阵列的可视化
下面是一个5阶Costas数组的可视化图。

从图中可以看出,没有两个点在同一行或同一列,但不明显的是,所有的连接线都是不同的。为了看出这些线是不同的,我们把所有连接线的尾巴移到原点,保持它们的长度和方向不变。

在第一幅图中有10条彩色线条,但起初你可能只看到第二幅图中的9条。这是因为其中两条线的方向相同但长度不同。如果你仔细观察,你会发现在长的红线上面有一条短的紫线。也就是说,一条线从原点到(1,-1),另一条从原点到(4,-4)。
这里是一个9阶的Costas阵列的可视化。

这是翻译到原点的位移向量。

这是一个阶数为15的Costas数组的视觉效果。

这里是它的位移向量翻译到原点。

生成Costas数组
有一些生成Costas数组的算法,但不是全部。每个已知的算法[1]都会遗漏一些解决方案,而且不知道某些n值的Costas数组是否存在。
上面的Costas数组是用Lempel构造算法生成的。给定一个素数p[2]和一个原始根modp[3],下面的Python代码将生成一个p-2阶的Costas数组。
p = 11 # prime
a = 2 # primitive element
# verify a is a primitive element mod p
s = {a**i % p for i in range(p)}
assert( len(s) == p-1 )
n = p-2
dots = []
for i in range(1, n+1):
for j in range(1, n+1):
if (pow(a, i, p) + pow(a, j, p)) % p == 1:
dots.append((i,j))
break