假设我们给出正整数的数组B
和A
。 B
和U
包含相同的整数(相同的次数),因此它们的长度自然相同。
如果V
为U[i] != V[i]
,请考虑将两个数组i = 0, 1, ..., len(U) - 1
和A
的排列设为有效。
我们希望为B
和import random
def random_valid_permutation(values):
A = values[:]
B = values[:]
while not is_valid_permutation(A, B):
random.shuffle(A)
random.shuffle(B)
return A, B
def is_valid_permutation(A, B):
return all([A[i] != B[i] for i in range(len(A))])
找到一对有效的排列。但是,我们希望我们的算法能够同样返回所有有效排列对。
我今天一直在研究这个问题,似乎无法提出一个时髦的解决方案。这是迄今为止我最好的解决方案:
grep -F '-F' file
不幸的是,由于这种方法涉及每个数组的随机混洗,理论上它可以花费无限的时间来产生有效的输出。我提出了一些做在有限(和合理)时间内运行的替代方案,但它们的实现时间要长得多。
有没有人知道解决这个问题的简单方法?
答案 0 :(得分:0)
首先请注意,每个排列A与任何其他排列A具有相同数量的排列B.因此,生成单个A然后生成随机B就足以获得匹配。已知排列B是A的紊乱的概率是(大约)1 / e(略好于3中的1),其方式基本上与项目的数量无关。您有超过99%的可能性会在不到12个试验中找到有效的B.除非您的值列表很大,否则使用内置random.shuffle
进行捕获可能比滚动自己的更快,因为如果项目的每个新位置都会导致冲突,则检查项目的开销。以下几乎是瞬间的千元素,并且只需要大约一秒钟左右的百万元素:
import random
def random_valid_permutation(values):
A = values[:]
B = values[:]
random.shuffle(A)
random.shuffle(B)
while not is_valid_permutation(A, B):
random.shuffle(B)
return A, B
def is_valid_permutation(A, B):
return all(A[i] != B[i] for i in range(len(A)))
作为优化 - 我删除了[
和]
形成is_valid_permutation()
的定义,因为all
可以直接处理生成器表达式。没有理由在内存中创建整个列表,因为通常在列表结束之前很久就会检测到任何冲突。