什么是一个好的一次伪随机随机播放?

时间:2011-07-21 04:21:40

标签: algorithm math random shuffle

Fisher-Yates shuffle提供了一个很好的算法,可以在一次传递中对长度为A的数组n进行混洗:

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]

通过此算法单次传​​递的结果分布均匀随机,并且对此帖子的内容进行了很好的讨论:What distribution do you get from this broken random shuffle?

我最近阅读了Diaconis,Fulman和Holmes题为Analysis of Casino Shelf Shuffling Machines的一篇令人愉快的文章,其中作者描述了一个物理机器进行以下批量洗牌:

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张牌。

是否有任何其他有趣的单通道随机播放实现近乎随机性和/或有趣的分布?我特别感兴趣的是与后者相似的shuffle,这些shuffle适用于批量条目。

1 个答案:

答案 0 :(得分:1)

如果你有一个洗牌桌,你希望将一批新牌洗牌(你知道没有一张牌是重复的),那么我认为以下内容是有效的。

ForEach card in batch:
    gap = random(deck.size() + 1)  # choose a gap between cards, before first, or after last.
    deck.insertAt(gap,card)

分发

随机的分布是均匀的,并且甲板的顺序不变,所以仍然是均匀的。 我认为结果应该是统一的。 (我的统计数据太生锈了,无法确定)。

时间

假设insertAt是O(1)而不是O(N) - 这取决于套牌的实现 - 整个例程是O(批量大小) - 这是你希望最好的,因为你必须处理每张卡