【发布时间】:2017-06-12 06:41:27
【问题描述】:
我想随机生成前 n 个自然数的排列 P,并且它必须满足每个 i<n 的 P[i] != i。
我怎样才能有效地做到这一点?
我想出的第一个方法就是迭代地为每个位置随机选择合法数字。但是我发现它似乎并不能保证随机性。
例如在4个号码的情况下,如果我(随机)选择2,3作为前两个号码,那么最后两个号码的配置可以是0,1或1,0。如果我碰巧选择1,2 作为前两个,那么剩下的唯一可用选项是3,0,因为最后一位不能是3。所以看来1,2,3,0的概率是2,3,0,1的两倍吧?
另外一个办法就是随机生成一个排列,如果不满足条件就拒绝,但是这个时间复杂度不能保证。
【问题讨论】:
-
你的意思是“均匀分布”。 “随机”并不是说概率相等。
-
@Henry 对,我的意思是“均匀分布”确实
-
您可以使用Fisher-Yates Shuffle 来随机化初始序列。万一,一个元素被错误地放置,将它与它的邻居交换。如果错误放置了更多元素,请对这些元素执行第二次 Fisher-Yates shuffle。
-
对于较大的 n,排列没有固定点的概率趋于 1/e。因此,拒绝具有固定点的排列的策略平均需要 e (2.718...) 次尝试。在无限制排列的生成过程中,如果您检测到将有一个固定点来加快处理速度,您也可以“快速失败”。所以这在实践中不应该表现得太糟糕。
-
@Henry 很高兴知道这一点,谢谢
标签: algorithm random combinations permutation