【问题标题】:What's the best way to generate unique permutations in Python?在 Python 中生成唯一排列的最佳方法是什么?
【发布时间】:2020-07-17 12:07:51
【问题描述】:

对于每个项目,我有 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 个唯一组合。但我想这些只是示例值
  • 谢谢,是的,我有10多个项目,我只是想举一些简单的例子。

标签: python random combinations sequence combinatorics


【解决方案1】:
  • 这是一个二进制数,每个唯一的二进制数对应一个 唯一的小数。
  • 有 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(" ", "")

【讨论】:

  • 当我运行它,我得到的值是这样的:1111101110 1001101 11011000 110010000 1110110101 1010111000 1111011111 1110110111 111000101 11110010,并不是所有的他们有10位,还是我失去了一些东西 SPAN>
  • 你编辑了吗?我可能不得不使用你的答案,因为我需要这个来扩展。
  • 最后一行出现语法错误,不确定是否有效?
  • 非常感谢它现在可以工作了。您如何控制总共获得多少物品与拥有多少位数?我把size改成20了,还是显示10位数,不知道有没有办法控制这些。
  • 已更新。通过n_digitsn_samples控制
猜你喜欢
  • 1970-01-01
  • 2010-09-30
  • 1970-01-01
  • 2011-01-25
  • 2013-01-20
  • 1970-01-01
  • 2010-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多