【发布时间】:2011-01-28 09:24:14
【问题描述】:
你会说现代版的 Fisher yates 是最公正的洗牌算法吗? 你如何解释数组中的每个元素都有 1/n 的概率位于其原始位置?
【问题讨论】:
-
@pajton:+1 以获得最佳答案;)
-
我不确定某些东西是否是“最公正的”。如果它是无偏的,那么就洗牌结果而言,它等同于任何其他无偏算法(它仍然可以在时间、空间等方面有所不同)
你会说现代版的 Fisher yates 是最公正的洗牌算法吗? 你如何解释数组中的每个元素都有 1/n 的概率位于其原始位置?
【问题讨论】:
给定一个完美的伪随机数生成器(Mersenne Twister 非常接近),Fisher-Yates 算法是完全无偏的,因为每个排列都有相同的发生概率。使用归纳法很容易证明这一点。 Fisher-Yates 算法可以递归编写如下(Python 语法伪代码):
def fisherYatesShuffle(array):
if len(array) < 2:
return
firstElementIndex = uniform(0, len(array))
swap(array[0], array[firstElementIndex])
fisherYatesShuffle(array[1:])
每个索引都有相同的概率被选为firstElementIndex。当你递归时,你现在有相同的概率选择任何剩余的元素。
编辑:算法已在数学上被证明是无偏的。由于该算法是不确定的,因此测试实现是否正常工作的最佳方法是统计。我会采用一些任意但小尺寸的数组,将其洗牌多次(每次从与输入相同的排列开始)并计算每个输出排列发生的次数。然后,我会使用Pearson's Chi-square Test 来测试这个分布的一致性。
【讨论】:
(现代,又名“Knuth”)Fisher–Yates shuffle 是
我们还想从算法中得到什么(嗯,是的,当排列的数量变得巨大时,人们可能会尝试其他方法,但大多数情况并不涉及如此庞大的计数)?
编辑:
' 只是注意到这个答案响应了问题的标题,而不是它的内容。 (这就是为什么最好让问题的这两个部分更好地匹配......)
简而言之,随机播放将与用于实现算法的特定 RNG 一样随机。
一个直观的解释是,对于具有 m 个元素的数组,即使作为 n,循环的递减控制变量下降到 1,位置 n 的单元格可能被交换的可能单元格减少,这个单元格的概率很容易被移动以完全相同的比例增加。换句话说,数组的最后一个元素可以在数组中的任何位置结束,但它只有一次移动的机会(在第一次迭代时)。要移动的倒数第二个元素少了一个位置,但有 1/m 的概率它可能在第一次迭代期间很容易被移动。等等
【讨论】: