【发布时间】:2020-05-23 16:18:44
【问题描述】:
我希望随机生成derangements。换句话说:打乱一个向量,以便没有元素留在原来的位置。
要求:
- 均匀采样(每个紊乱以相同的概率生成)
- 实际实现比拒绝方法更快(即不断生成随机排列,直到我们发现紊乱)
到目前为止,我找到的答案都不是令人满意的,因为它们要么不均匀采样(或无法证明均匀性),要么没有与拒绝方法进行实际比较。大约1/e = 37% 的排列是混乱的,它提供了一个线索,即相对于拒绝方法,人们最多可以期望什么性能。
我发现的唯一一个进行实际比较的参考是this thesis,他们提出的算法基准为 7.76 秒,拒绝方法基准为 8.25 秒(参见第 73 页)。这仅是 1.06 倍的加速。我想知道是否有可能更好(> 1.5)。
我可以实现和验证论文中提出的各种算法,并对它们进行基准测试。正确地做到这一点需要相当多的时间。我希望有人做过,并且可以给我参考。
【问题讨论】:
-
你看过Fisher-Yates shuffle吗?
-
@dbush 这是一种用于对所有排列进行均匀采样的算法,而不是用于采样紊乱的算法。这是我在问题中提到的“拒绝方法”的一部分。
-
我可以想到一种算法,但它需要一个辅助缓冲区。您在寻找无额外缓冲区算法吗?
-
@acegs 我我对在新缓冲区中构造混洗向量的算法感兴趣。那个应该以同样使用新缓冲区的 Fisher-Yates 为基准。
-
最好的事情实际上可能是拒绝方法的一种变体,一旦明确结果不会是混乱,它就会重新开始生成。此处对此进行了描述:stackoverflow.com/a/25238398/695132
标签: c++ algorithm performance permutation shuffle