python - 在 Python 中生成独特排列的最佳方法是什么?

标签 python random combinations sequence combinatorics

对于每个项目,我有 0 和 1 之间的 2 个选择,其中 N 个元素依次排序,生成唯一的组合。

像这样的东西(序列长度=10):

0, 1, 0, 1, 0, 1, 0, 1, 0, 1
0, 0, 0, 1, 0, 1, 0, 1, 0, 1
0, 1, 1, 1, 0, 1, 0, 1, 0, 1
1, 1, 1, 1, 0, 1, 0, 1, 0, 1

如您所见,这些都是独特的排列。我将有 10000 个这样的排列(例如)。但关键信息是我不需要所有排列,而只保存有限的一组排列,并且最好是无序的,因此它更加“随机”。

我当前的解决方案是生成 0 到 1 之间的随机数,并将它们附加到最多 N 个元素的数组中。然后将此数组转换为字符串,如果该字符串尚未添加到上面的列表中,则添加它,否则重复相同的步骤以生成不同的排列。

这意味着使用 while 循环。

是否有更聪明、或更优雅的方法来做到这一点?

最佳答案

  • 这是一个二进制数,每个唯一的二进制数对应一个 唯一的小数点。
  • 10 个位置中,有 2^10 = 1024 个唯一位置。
  • 从这 1024 个中选择 10 个,不进行替换
  • 将十进制转换为二进制

生成 5 个独特的样本,每个样本 10 位

import numpy as np
n_digits = 10
n_sample = 5
for c in np.random.choice(np.power(2,n_digits), size=n_sample, replace=False):
  c = int("{0:b}".format(c))
  print (str(c).zfill(n_digits))

示例运行

0100011110
0110110011
0100110001
1110011100
1110101011

编辑:

上面的代码速度很快,但不会扩展到更大的数字,因为 np.power(2,n_digits) 也会导致溢出,np.random.choice 也会内存不足。

为了将其扩展到非常大的序列,我们可以使用有点慢但非常不错的机制,如下所示

n_digits = 200
n_sample = 10000
choices = []
cache = {}
while len(choices) < n_sample:
    c = np.random.randint(0,2,(n_digits))
    k = c.tostring()
    if not k in cache:
        cache[k] = True
        choices.append(c)

%timeit 返回

27.4 ns ± 10.1 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

这相当不错。

choices 是 numpy 数组的列表,如果你想将其转换为文本,你可以使用

for i in range(len(choices)):
    choices[i] = np.array2string(choices[i], separator='')[1:-1].replace("\n", "").replace(" ", "")

关于python - 在 Python 中生成独特排列的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62953639/

相关文章:

python - ipython 无法在 Windows 上运行

Ruby #detect 使用随机数的行为

Python Heads Or Tails 程序帮助

python - 玛雅Python : OptionMenu Selection With Button

javascript - Js 文件加载不正确

python - 使用 pandas 将年、月、日列合并为单个日期列

c++ - 如何偏置随机数生成器

php - 我如何结合这两个查询来计算排名变化?

java - 找到组合,给定 n 个盒子和 x 个球

matlab - 在 Matlab 中随机选择所有可能组合的子集?