【问题标题】:Shuffle a long list an even longer number of times in Python在 Python 中随机播放一个长列表的次数甚至更长
【发布时间】:2018-04-02 05:23:39
【问题描述】:

我想多次(比如 10000)洗牌一个长序列(比如它有超过 10000 个元素)。在阅读Python Random documentation时,发现如下:

请注意,即使对于较小的 len(x),x 的排列总数也会迅速增长,大于大多数随机数生成器的周期。这意味着永远无法生成长序列的大多数排列。例如,一个长度为 2080 的序列是在 Mersenne Twister 随机数发生器的周期内可以拟合的最大序列

我有两组(可能更多),每组都有很多值。我要洗牌的序列是所有可用值的列表,无论组如何。我担心的是该注释暗示我需要的随机播放可能不是由 random.shuffle() 函数提供的。

我想过一些解决方法:

  • 在某些迭代中多次初始化随机数生成器(使用 random.seed())。这样一来,排列是否超过周期无关紧要,因为不同的种子会得到不同的结果。
  • 使用样本(范围(序列长度),k=组大小)获取随机索引,然后使用这些索引在每个组中进行索引。这样我就不会因为随机数生成器的周期而用完排列。

我的任何替代方案都有帮助吗?

非常感谢!

【问题讨论】:

  • 我不同意@sasha:如果不是所有排列都可以以相同的概率达到,那么洗牌就不会是完全随机的——会有一定的可预测性可以被利用。
  • @OP,您可能想查看crypto 模块,看看它是否提供了您可以使用的替代方案?
  • 我在 Random 包中看到了 shuffle 功能。我现在更加困惑了。我不知道我是否应该关注 al github.com/python/cpython/blob/3.6/Lib/random.py

标签: python algorithm python-3.x random montecarlo


【解决方案1】:

10,000! ~= 10^36,000 那是很多可能的排列。您能做的最好的事情就是深入研究您的操作系统或硬件如何累积“真正随机”的位。然后,您可以等待大约 120,000 位您可以接受的随机性,然后使用在给定随机 n 的情况下生成输入列表的第 n 个排列的算法。

【讨论】:

  • 这里的问题是排列发生的顺序和数量。要按您说的进行选择,我想我需要存储所有可能的排列,这是不可能的。
  • 不,有一种独特的算法,您可以在其中给它一个列表,以及所需排列的“索引”,它会吐出它而不会像所有排列一样生成任何地方。我以前用过,也发过,但是要十分钟才能找到……
  • ...啊,here是我开始的Rosetta Code任务;和here 我在 SO 上回答了类似的任务。
【解决方案2】:

您可以使用numpy shuffle function 就地打乱列表元素

import numpy as np

L = range(0, 10000)
np.random.shuffle(L)

定时随机调用(在 Jupyter 中)

%timeit np.random.shuffle(L)

你得到

10000 loops, best of 3: 182 µs per loop

【讨论】:

  • 这能解决 OP 的问题吗?
  • 这并不能解决问题 Juan Ardave:你可以看到 here numpy random 也使用了 mersene twister 生成器。
猜你喜欢
  • 2011-03-05
  • 2018-09-29
  • 2014-04-02
  • 1970-01-01
  • 1970-01-01
  • 2023-01-23
  • 2010-12-04
  • 1970-01-01
  • 2022-12-10
相关资源
最近更新 更多