29

我有一个包含 27 个元素的数组,我不想生成数组的所有排列(27 个!)我需要 5000 个随机选择的排列,任何提示都会很有用......

4

6 回答 6

41

要生成一个排列,请使用random.shuffle并存储结果的副本。在循环中重复此操作,每次检查是否有重复项(但可能不会有任何重复项)。一旦您的结果集中有 5000 个项目,请停止。

为了解决评论中的问题,Python 的random 模块基于Mersenne Twister并且有一个2**19937-1,它比它大得多,27!因此它应该适合您的使用。

于 2010-01-23T19:17:12.077 回答
12
import random

perm_list = []

for i in range(5000):
    temp = range(27)
    random.shuffle(temp)
    perm_list.append(temp)

print(perm_list)

10888869450418352160768000000 我喜欢大数字!:)

10888869450418352160768000001是首要的!

编辑:

#with duplicates check as suggested in the comment

perm_list = set()
while len(perm_list)<5000:
    temp = range(27)
    random.shuffle(temp)
    perm_list.add(tuple(temp)) # `tuple` because `list`s are not hashable. right Beni?

print perm_list

警告:如果 RNG 不好,这将永远不会停止!

于 2010-01-23T19:16:25.833 回答
6

itertools.permutations. 它是一个生成器,因此它不会创建整个排列列表。您可以随机跳过,直到获得 5000。

于 2010-01-23T19:14:14.800 回答
6
# apermindex should be a number between 0 and factorial(len(alist))
def perm_given_index(alist, apermindex):
    for i in range(len(alist)-1):
        apermindex, j = divmod(apermindex, len(alist)-i)
        alist[i], alist[i+j] = alist[i+j], alist[i]
    return alist

用法:perm_given_index(['a','b','c'], 3)

这将 Lehmer 代码用于排列作为j匹配的值。

于 2010-07-13T21:59:20.587 回答
2

您可以尝试实施random_permutation itertools recipes。为方便起见,我使用了一个第三方库,more_itertools它为我们实现了这个秘诀:

import more_itertools as mit

iterable = range(27)
mit.random_permutation(iterable)
# (24, 3, 18, 21, 17, 22, 14, 15, 20, 8, 4, 7, 13, 6, 25, 5, 12, 1, 9, 19, 23, 11, 16, 0, 26, 2, 10)

每次调用函数都会创建一个随机排列。n我们可以制作一个生成器来为调用产生这些结果。我们将实现这个生成器并用一个简短的例子演示随机结果:

def random_permute_generator(iterable, n=10):
    """Yield a random permuation of an iterable n times."""
    for _ in range(n):
        yield mit.random_permutation(iterable)

list(random_permute_generator(range(10), n=20))
# [(2, 7, 9, 6, 5, 0, 1, 3, 4, 8),
#  (7, 3, 8, 1, 2, 6, 4, 5, 9, 0),
#  (2, 3, 1, 8, 7, 4, 9, 0, 6, 5),
#  (0, 5, 6, 8, 2, 3, 1, 9, 4, 7),
#  (0, 8, 1, 9, 4, 5, 7, 2, 3, 6),
#  (7, 2, 5, 8, 3, 4, 1, 0, 9, 6),
#  (9, 1, 4, 5, 8, 0, 6, 2, 7, 3),
#  (3, 6, 0, 2, 9, 7, 1, 4, 5, 8),
#  (8, 4, 0, 2, 7, 5, 6, 1, 9, 3),
#  (4, 9, 0, 5, 7, 1, 8, 3, 6, 2)
#  ...]

对于您的具体问题,用适当的值替换可迭代和调用次数n,例如random_permute_generator(iterable, n=5000).

有关此工具的更多信息,另请参阅more_itertools文档


细节

对于那些感兴趣的人,这里是实际的食谱。

itertools 食谱

def random_permutation(iterable, r=None):
    "Random selection from itertools.permutations(iterable, r)"
    pool = tuple(iterable)
    r = len(pool) if r is None else r
    return tuple(random.sample(pool, r))
于 2017-08-30T20:31:19.127 回答
1

您可能需要 itertools.permutations() 函数。一定会喜欢那个 itertools 模块!

注意:2.6 中的新功能

于 2010-01-23T19:14:54.813 回答