为什么以下代码不会随机生成排列?

时间:2011-07-31 15:27:39

标签: algorithm permutation

  

可能重复:
  What distribution do you get from this broken random shuffle?

这是来自Skiena的算法设计手册。

假设myrand(a,b)在a和b之间生成一个随机数。

以下代码随机均匀生成排列

for(int i = 0; i < n; i++)
    swap( a[i], a[myrand(i, n-1)]);

而以下情况则不然。

for(int i = 0; i < n; i++)
    swap( a[i], a[myrand(0, n-1)]);

问题是,为什么?

1 个答案:

答案 0 :(得分:2)

在第一种情况下,确切地说是n!执行函数的可能路径(第一个rand有n种可能性,第二个有n-1 ......)。既然每个都是n!可能的排列恰恰相反,它们是均匀分布的。

在第二种情况下,有n ^ n个可能的分布路径(第一次是n个可能的chioc,第二个是n ......)。这统一映射到排列,因此分布不均匀。

要“手动”查看,请为小n生成所有可能性,例如3

numbers chosen  generated permutation
(0,0,0)         (2,0,1)
...              ...