用[i]!= i进行随机置换

时间:2012-03-07 09:15:19

标签: permutation probability discrete-mathematics

通常,具有n个元素的数组的随机排列意味着n!种可能性的均匀分布,而Knuth shuffle用于这样做:

for i from n − 1 downto 1 do
  j ← random integer with 0 ≤ j ≤ i
    exchange a[j] and a[i]

但是由于约束a[i] != i,我不知道如何统一形成这样的排列。

例如,如果n = 3,如何从下面的可能性中随机形成一个排列?

{1, 2, 0}, {2, 0, 1}

2 个答案:

答案 0 :(得分:2)

没有固定点的排列称为derangement

由于derangemets的数量是 O(n!),就像排列的数量一样,生成所有排列并过滤那些不是排列的排列不会影响你的表现。

快速搜索返回了我these slides,它描述了另一种算法。

答案 1 :(得分:0)

您没有说明您的阵列有多大或者您对效率的关注程度如何。一种可能的解决方案就是做Knuth shuffle,然后测试你的约束是否满足,如果不满足则重做shuffle。

如果你想要更高效率,你可以试试这个。由于i正在减少,因此在步骤exchange a[j] and a[i]之后,a[i]已得到修复。因此,只需将算法修改为:

for i from n − 1 downto 1 do
  j ← random integer with 0 ≤ j ≤ i; repeat until a[j] != i
    exchange a[j] and a[i]