更新的答案
从Walter Tross代码的示例输出中可以看出,生成随机解决方案可以简化为以下步骤:
首先选定任意向量作为起始点,例如n=8、m=3、k=5:
A: 01001100
每一步之后,将向量求和以得到每个位置被使用的次数:
SUM: 01001100
然后,对于下一个向量,将数字放置在已使用最少的位置(在本例中为零次),例如:
B: 00110001
需要获取:
A: 01001100
B: 00110001
SUM: 01111101
接下来,还剩下两个最少使用的位置,所以对于下一个向量中的三个数字,使用这两个位置,然后将第三个数字放在任何位置:
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×4=627,200种n=8,m=3,k=5的解决方案。
实际上,您需要添加一个避免重复向量的方法,并避免让自己陷入困境。因此,我认为这不会比沃尔特的答案更简单。
初始答案 - 存在主要问题
(我将假设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就是重叠的次数,即一个向量与前一个向量在同一位置上有1的次数。然后,您将重叠均匀分布在不同的向量上,以最大化总距离。
在上面的示例中,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
- 对于每一个向量A,生成所有比向量A小的字典序向量B,并且与向量A有相同数量的重叠1(在本例中为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的值;我不确定它是否可以适用于一般情况。
1001
、0101
、0110
和1010
,当与1100
进行比较时,它们是否都相距相同的“距离”,因为它们在两个位上都不同? - Joseph Wood