更新答案
查看 Walter Tross 代码的示例输出,我认为生成随机解可以简化为:
以任何向量开头,例如对于 n=8,m=3,k=5:
A: 01001100
每一步之后,对向量求和,得到每个位置被使用的次数:
SUM: 01001100
然后,对于下一个向量,将它们放在最少使用的位置(在本例中为零次),例如:
B: 00110001
得到:
A: 01001100
B: 00110001
SUM: 01111101
那么,剩下2个最少使用的位置,所以对于下一个向量中的3个,使用这2个位置,然后将第三个放在任何位置:
C: 10010010
得到:
A: 01001100
B: 00110001
C: 10010010
SUM: 11121111 (or reset to 00010000 at this point)
然后对于下一个向量,您有 7 个最少使用的位置(总和中的位置),因此选择任意 3 个,例如:
D: 10100010
得到:
A: 01001100
B: 00110001
C: 10010010
D: 10100010
SUM: 21221121
对于最终向量,选择 4 个最少使用的位置中的任何一个,例如:
E: 01000101
要生成所有解决方案,只需在每个步骤中生成每个可能的向量:
A: 11100000, 11010000, 11001000, ... 00000111
然后,例如当 A 和 SUM 为 11100000 时:
B: 00011100, 00011010, 00011001, ... 00000111
然后,例如当 B 为 00011100 且 SUM 为 11111100 时:
C: 10000011, 01000011, 00100011, 00010011, 00001011, 00000111
然后,例如当 C 为 10000011 且 SUM 为 21111111 时:
D: 01110000, 01101000, 01100100, ... 00000111
最后,例如当 D 为 01110000 且 SUM 为 22221111 时:
E: 00001110, 00001101, 00001011, 00000111
这将导致 C(8,3) × C(5,3) × C(8,1) × C(7,3) × C(4,3) = 56 × 10 × 8 × 35 ×对于 n=8、m=3、k=5,4 = 627,200 个解。
其实你需要加一个方法,避免重复同一个向量,避免把自己画到角落里;所以我认为这不会比沃尔特的回答更简单。
初步答案 - 存在重大问题
(我假设m不大于n/2,即1的个数不大于0的个数。否则,使用对称方法。)
当k×m不大于n时,显然存在最优解,例如:
n=10, m=3, k=3:
A: 1110000000
B: 0001110000
C: 0000001110
汉明距离都是2×m:
|AB|=6, |AC|=6, |BC|=6, total=18
当 k×m 大于 n 时,连续向量之间的汉明距离差异最小的解决方案提供最大的总距离:
n=8, m=3, k=4:
A: 11100000
B: 00111000
C: 00001110
D: 10000011
|AB|=4, |AC|=6, |AD|=4, |BC|=4, |BD|=6, |CD|=4, total=28
n=8, m=3, k=4:
A: 11100000
B: 00011100
C: 00001110
D: 00000111
|AB|=6, |AC|=6, |AD|=6, |BC|=2, |BD|=4, |CD|=2, total=26
所以,实际上,你取 m×k 看看它比 n 大多少,我们称它为 x = m×k−n,这个 x 是重叠的数量,即一个向量多久会有一个一个与前一个向量在同一位置。然后,您尽可能均匀地将重叠分布在不同的向量上,以最大化总距离。
在上面的例子中,x = 3×4−8 = 4,我们有 4 个向量,所以我们可以均匀地展开重叠,每个向量在与前一个向量相同的位置有 1 个。
要生成所有独特的解决方案,您可以:
- 计算 x = m×k−n 并将 x 的所有分区生成 k 个部分,并具有尽可能小的最大值:
n=8, m=3, k=5 -> x=7
22111, 21211, 21121, 21112, 12211, 12121, 12112, 11221, 11212, 11122
(discard partitions with value 3)
A: 11100000, 11010000, 11001000, 11000100, ... 00000111
- 对于其中的每一个,生成所有向量 B,它们在字典上小于向量 A,并且与向量 A 有正确的重叠数量(在示例中为 1 和 2),例如:
A: 10100100
overlap=1:
B: 10011000, 10010010, 10010001, 10001010, 10001001, 10000011, 01110000, ... 00000111
overlap=2:
B: 10100010, 10100001, 10010100, 10001100, 10000110, 10000101, 01100100, ... 00100101
- 对于其中的每一个,生成所有向量 C,依此类推,直到你有 k 个向量的集合。在生成最后一个向量时,您必须考虑与前一个向量以及下一个(即第一个)向量的重叠。
我认为最好将 x 到 k 的分区视为二叉树:
1 2
11 12 21 22
111 112 121 122 211 212 221
1112 1121 1122 1211 1212 1221 2111 2112 2121 2211
11122 11212 11221 12112 12121 12211 21112 21121 21211 22111
并在创建解的同时遍历这棵树,这样每个向量只需要生成一次。
我认为这种方法只适用于 n、m 和 k 的某些值;我不确定它是否适用于一般情况。