我一直在玩一个奇怪的问题,已经有几个星期了,似乎无法获得想要的结果。
我想对对象列表进行排列以获得唯一的对。然后以特定方式对它们进行排序,以最大程度地使对象在列表中的任何位置均匀分布。这也意味着,如果一个对象在一对的开始处,则也应该在之后的一对结束时。没有对可以重复。为了澄清,这是一个示例。
列表(A,B,C,D)可能会导致以下结果:
(A,B)
(C,D)
(B,A)
(D,C)
(A,C)
(B,D)
(C,A)
(D,B)
(A,D)
(B,C)
(D,A)
(C,B)
注意,每个字母每2对使用一次,并且字母频繁切换位置。
要获得排列,我使用了python脚本:
perm = list(itertools.permutations(list,2))
给了我12对字母。
然后,我手动排序对,以便尽可能频繁地选择每个字母并尽可能频繁地切换位置。在列表中的任何时候,字母将非常平均地分布。当我解决这个问题的过程时,我知道列表中的哪个位置将停止,但我不知道这对配对的放置顺序有多大影响。
使用4个字母可以更容易实现,因为(4个字母/ 2对)= 2。 我也希望这也适用于奇数排列对。
例如:
A,B.C
A,B,C,D,E
等等。
我已经尝试了许多方法并试图识别模式,尽管有很多方法,但是尤其有很多方法可以解决此问题。可能还没有一个完美的答案。
我还尝试过对字母P(4,4)进行正常排列,或者对5个字母P(5,5)进行了排列,并且尝试了某些排列,将它们组合在一起,然后切碎成对。这似乎是另一条路线,但除非手动进行,否则我似乎无法弄清楚该选择哪对。
感谢您的帮助!也许尝试为我指出正确的方向:)
我最终将尝试将其实现到python中,但是我不一定需要帮助来编写代码。这更多地是关于流程可能是一个问题。
答案 0 :(得分:3)
“最大均等分布”的含义尚未明确定义。一个给定值的两个幻影之间可以考虑的最大对数。我会留给您展示一下我在此给出的方法相对于此的效果。
对于n个对象,我们有n *(n-1)对。在这些(a, b)
对中
n的索引为b =(a + 2)模n
以此类推。
我们可以生成前1对n相差1,然后生成n对2相差...
对于每个差异,我们通过将差异添加到索引(模n)来生成索引。当我们得到一个已经用于解决这种差异的a
时,我们加1
(再次取模n)。这样,我们可以产生具有这种差异的n对。当我们在索引中“滚动”时,我们确定每个值都会定期出现。
def pairs(n):
for diff in range(1, n):
starts_seen = set()
index = 0
for i in range(n):
pair = [index]
starts_seen.add(index)
index = (index+diff) % n
pair.append(index)
yield pair
index = (index+diff) % n
if index in starts_seen:
index = (index+1) % n
pairs2 = list(pair for pair in pairs(2))
print(pairs2)
# [[0, 1], [1, 0]]
pairs3 = list(pair for pair in pairs(3))
print(pairs3)
# [[0, 1], [2, 0], [1, 2],
# [0, 2], [1, 0], [2, 1]]
pairs4 = list(pair for pair in pairs(4))
print(pairs4)
# [[0, 1], [2, 3], [1, 2], [3, 0], <- diff = 1
# [0, 2], [1, 3], [2, 0], [3, 1], <- diff = 2
# [0, 3], [2, 1], [1, 0], [3, 2]] <- diff = 3
pairs5 = list(pair for pair in pairs(5))
print(pairs5)
# [[0, 1], [2, 3], [4, 0], [1, 2], [3, 4],
# [0, 2], [4, 1], [3, 0], [2, 4], [1, 3],
# [0, 3], [1, 4], [2, 0], [3, 1], [4, 2],
# [0, 4], [3, 2], [1, 0], [4, 3], [2, 1]]
# A check to verify that we get the right number of different pairs:
for n in range(100):
pairs_n = set([tuple(pair) for pair in pairs(n)])
assert len(pairs_n) == n*(n-1)
print('ok')
# ok