【问题标题】:Random valid permutations of an array in Python [duplicate]Python中数组的随机有效排列[重复]
【发布时间】:2015-11-28 08:08:34
【问题描述】:

假设给定数组AB 的正整数。 AB 包含相同的整数(相同的次数),所以它们的长度自然相同。

如果U[i] != V[i] 对应i = 0, 1, ..., len(U) - 1,则考虑两个数组UV 的排列有效

我们想为AB 找到一对有效的排列。但是,我们希望我们的算法能够使所有有效排列对都同样可能被返回。


我今天一直在解决这个问题,但似乎无法提出一个巧妙的解决方案。这是迄今为止我最好的解决方案:

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))])

不幸的是,由于这种方法涉及每个数组的随机洗牌,理论上它可能需要无限的时间才能产生有效的输出。我已经提出了几个确实在有限(且合理)时间内运行的替代方案,但它们的实施时间要长得多。

有人知道解决这个问题的巧妙方法吗?

【问题讨论】:

标签: python arrays algorithm permutation


【解决方案1】:

首先请注意,每个排列 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 可以直接作用于生成器表达式。没有理由在内存中创建整个列表,因为任何冲突通常会在列表结束之前很久检测到。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-11
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 2012-10-11
    • 1970-01-01
    相关资源
    最近更新 更多