什么是好的一次性伪随机洗牌?

发布于 2024-11-25 03:16:00 字数 1284 浏览 1 评论 0原文

Fisher-Yates shuffle 提供了一个很好的算法来对数组进行洗牌<单次传递长度为 n 的 code>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]

通过该算法单次传​​递的结果分布不是均匀随机,这篇文章对它是什么进行了很好的讨论:< a href="https://stackoverflow.com/questions/5131341/what-distribution-do-you-get-from-this-broken-random-shuffle">你从这个破碎的随机洗牌中得到什么分布?

我最近读过Diaconis、Fulman 和 Holmes 撰写的一篇令人愉快的文章,题为 赌场货架洗牌机分析,其中作者描述了一种物理执行以下批量洗牌的机器:

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

是否有任何其他有趣的单遍洗牌可以实现近乎随机和/或有趣的分布?我对类似于后者的批量条目的洗牌特别感兴趣。

The Fisher-Yates shuffle gives a nice algorithm to shuffle an array A of length n in a single pass:

For k = 1 to n
    Pick a random integer j from k to n
    Swap A[k] and A[j]

After a single pass through this algorithm, the entries of A occur uniformly at random.

A common way to botch this algorithm is to do the following:

For k = 1 to n
    Pick a random integer j from 1 to n
    Swap A[k] and A[j]

The resulting distribution from a single pass through this algorithm is not uniformly random, and there is a nice discussion of what it is at this post: What distribution do you get from this broken random shuffle?

I recently read a delightful article by Diaconis, Fulman and Holmes entitled Analysis of Casino Shelf Shuffling Machines where the authors describe a physical machine that does the following batch shuffle:

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

The question the authors address is whether or not this gives a reasonably random ordering after a single pass. The answer is decidedly not. One way to see the flaw in this shuffle is to start with a deck of cards that has n/2 red cards atop of n/2 black cards. The resulting deck after a single pass will have at most 10 clumps of red cards! For n = 52*6, this isn't terribly random. The authors also show that an optimal "guess the next card" strategy for the once shuffled will, on average, correctly guess 9.5 cards, whereas an optimal strategy for a random deck will average only 4.5 cards correctly guessed.

Are there any other interesting single-pass shuffles that achieve near-randomness and/or interesting distributions? I'm especially interested in shuffles similar to the latter that work with batches of entries.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晨与橙与城 2024-12-02 03:16:01

如果您有一个洗牌台,您希望将一批新牌洗入其中(并且您知道没有一张牌是重复的),那么我认为以下内容是有效的。

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(batch size) - 这是您可以希望的最好结果,因为您必须处理每张卡。

If you have a shuffled desk, into which you wish to shuffle a batch of new cards (and you know that none of the cards are duplicates), then I think the following is valid.

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

Distribution

The distribution of random is uniform, and the order of the deck is unchanged, so still uniform.
I think the result should be uniform. (My stats is too rusty to be sure).

Time

Assuming that insertAt is O(1) not O(N) - which depends upon the implementeation of deck - the whole routine is O(batch size) - which is the best you can hope for becuase you have to handle each card.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文