python - 这种洗牌算法是否以均匀的概率产生每个排列?

标签 python algorithm shuffle

我已经看到了一个特定的朴素洗牌算法是如何有偏见的,我觉得我基本上明白了这一点,并且我明白了 Fischer-Yates 算法如何没有偏见。我有以下算法,这是我在考虑如何洗牌列表时首先想到的算法。我知道它消耗两倍的内存并且运行时间不必要地长,但我仍然很好奇它是否产生具有均匀分布的每个排列,或者是否有一些我没有看到的隐秘原因导致它有偏差。

我还想知道随机洗牌是否还有其他一些“不需要的”属性,例如列表中各个位置填充某些值的概率是相关的。

def shuf(x):
    out = [None for i in range(len(x))]
    for i in x:
        pos = rand.randint(0,len(x)-1)
        while out[pos] != None:
            pos = rand.randint(0,len(x)-1)
        out[pos] = i
    return out

我在 20 个元素的列表上生成了该热图,运行了 10^6 次试验,并生成了以下结果。映射的 (i,j) 坐标表示列表的第 i 个位置被原始列表的第 j 个元素填充的概率。

enter image description here

虽然我没有看到热图的任何模式,但看起来方差可能很大。或者这可能是热图夸大了方差,因为,嘿,最小值和最大值必须出现在某个地方。

最佳答案

不良属性 - 如果您要洗牌一大组,这可能会很昂贵:

 while out[pos] != None:
            pos = rand.randint(0,len(x)-1)

想象一下 len(x) == 100,000,000 并且您已经放置了 90,000,000 - 在获得命中之前您将循环很多次。

有趣的练习:

  1. 在 10e6 次迭代中简单生成 1 到 len(x) 之间的随机数的热图是什么样子?

  2. 作为比较,Fischer-Yates 的热图是什么样的?

乍一看,在我看来,给定一个统一的 RNG,它应该产生真正的随机分布(尽管比 Fischer-Yates 慢)。

关于python - 这种洗牌算法是否以均匀的概率产生每个排列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27352244/

相关文章:

python - celery celerybeat 可以在运行时动态添加/删除任务吗?

python - 在 Cython 与 NumPy 中对整数与 float 求和时性能差异很大

algorithm - 找到 a^b^c^... mod m

python - 如何在 Python 中随机排列多个列表或数组?

java - 洗牌——数组还是堆栈?

python - 从合并列的代码中获取类别类型

python - 计算链表节点数

python - 知道一个项目在数组中的位置

c# - 有没有人有 C++ 和 C# 中的 CRC128 和 CRC256 代码?

c# - 识别文本消息之间相似性的算法