2012-03-07 72 views
1

一般用于具有n个元素的数组的随机排列是指从n!可能性的均匀分布,并且Knuth的洗牌是用来做这样:与[I]随机置换= I

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

但随着我不知道如何统一形成这样一个排列组合。

例如,n = 3,如何从下面的可能性中随机地构成一个置换?

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

回答

2

而不固定点排列称为derangement

作为derangemets的数目是为O(n!),就像排列的数目,生成的所有排列和过滤那些不紊乱不会伤害你的表现。

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

+1

谢谢,我还发现这个算法[这里]的正式文件(http://www.siam.org/proceedings/analco/2008/anl08_022martinezc.pdf)。 – peter 2012-03-08 02:36:10

0

你没有说明你的数组有多大,或者你对于效率的关心程度。一种可能的解决方案就是做Knuth 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] 
+0

复杂性并不重要,但我需要证明它是均匀分布的。满足约束的简单结果是不够的。 – peter 2012-03-07 09:31:03

+0

在了解你的随机函数是,那么这是。原始的Knuth洗牌均匀分布在所有烫发中 - 特别是它具有生成每个约束排列的相等机会。如果结果与约束不匹配,只要将结果扔掉,再次尝试不会改变结果。 – Chowlett 2012-03-07 09:35:09

+0

看看这个:http://stackoverflow.com/questions/7279895/shuffle-list-ensuring-that-no-item-remains-in-same-position,似乎这个算法已经被测试不是制服。 – peter 2012-03-08 02:29:28