通常,具有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}
答案 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]