之前我读到费雪耶茨,这是我想出了一个算法:
def sort(arr):
for i in range(len(arr)):
swap(arr, i, rand.randint(0, len(arr) - 1))
从我的理解,这和费雪耶茨之间的唯一区别在于不是:
swap(arr, i, rand.randint(0, len(arr) - 1))
我应该写:
swap(arr, i, rand.randint(i, len(arr) - 1))
有人能解释一下第一种算法是如何不正确? (即不产生一个随机洗牌)。
维基百科:
类似地,从有效阵列索引在每个迭代上的整个范围内总是选择j仍然产生的结果,其被偏置,尽管不那么明显如此。 这可以从以下事实可以看出,这样的产量N N互换的不同可能的序列,而只有N! 正元件阵列的可能的排列。 由于N N永远不能被n整除! 当n> 2(因为后者是整除n-1个,这股用正无素因子),一些置换必须由更互换比其他的N N序列的产生。 作为该偏压的一个具体的例子,观察的洗牌的三元件阵列[1,2,3]的可能结果的分布。 有此阵列的6个可能的排列(3!= 6),但该算法产生27个可能混洗(3×3 = 27)。 在这种情况下,[1,2,3],[3,1,2]和[3,2,1]从27个混洗的4各自结果,在每个剩余的3个排列在27 5发生洗牌。
从本质上讲,你引入了一个微妙的偏见进入洗牌,这将导致一些排列比别人更多的时候突然出现了一点。 它通常不是很明显,但它可以使(上排列如Monte Carlo模拟)一些敏感的应用不能产生准确的答案。