费雪-耶茨洗牌算法提供了一种很好的算法来在单次遍历中对长度为n
的数组A
进行洗牌:
For k = 1 to n
Pick a random integer j from k to n
Swap A[k] and A[j]
在这个算法中只需单次遍历,
A
的条目将会均匀随机出现。一个常见的搞砸此算法的方法是执行以下操作:
For k = 1 to n
Pick a random integer j from 1 to n
Swap A[k] and A[j]
这个算法单次通过后得到的分布不是均匀随机的,关于它的分布有一个很好的讨论在这篇文章中:这个破解乱序算法会得到什么样的分布?
我最近读了一篇名为分析赌场洗牌机的文章,作者描述了一个物理机器执行以下批量洗牌:
For k = 1 to n
Pick a random integer j from 1 to 10
Randomly choose to place card k on the top or bottom of stack j
作者要解决的问题是,是否在一次洗牌后可以得到相当随机的顺序。答案明显是否定的。看到这种洗牌方法的漏洞的一种方式是,从一副牌开始,其中有
n/2
张红色牌放在n/2
张黑色牌之上。经过一次洗牌后的牌堆中最多只会有10个红色牌堆!对于n = 52*6
,这不是非常随机。作者还表明,对于一次洗牌后的优化“猜下一张牌”的策略,平均而言,将正确猜测9.5张牌,而对于随机牌堆的最佳策略,平均而言只能正确猜测4.5张牌。
是否有其他有趣的单次洗牌方法可以实现接近随机的顺序和/或有趣的分布?我特别感兴趣的是类似于后者的批量条目洗牌。