Shuffle:为什么for循环切换arr [i]与arr [r](r:随机0 - 长度 - 1)不是均匀随机的混洗?

时间:2016-03-31 01:40:49

标签: random probability shuffle

我目前正在Coursera上学习Sedgewick的算法课程(用Java教授)。他说要创建一个统一随机的混洗算法,我必须遍历我的数组中的每个索引i,用一个随机元素交换该元素只从我已经看过的那些元素开始。他说如果我要用整个数组中的随机元素交换元素,那么它就不会是随机的。为什么不?如果每个迭代元素[I]与数组中的另一个元素完全随机交换,包括它自身,那么1 / N总是元素[I]最终结束的概率;我不知道如何引入偏见。

换句话说,他主张:

for (var i = 0; i < arr.length; i++){
  var r = Math.floor(Math.random() * i + 1)
  swap(r, i);
}

for (var i = 0; i < arr.length; i++){
  var r = Math.floor(Math.random() * arr.length)
  swap(r, i);
}

请原谅JavaScript,因为我是一名全新的程序员并且对此更加满意。:)

1 个答案:

答案 0 :(得分:0)

非常简单的数学。如果你从整个集合中切换另一个元素,你最终会得到一个从0到N-1,N次的随机数,所以有N ** N个可能的结果。既然有N! (即阶乘N)项目的可能安排,N ** N不能被N!整除,某些安排会比其他安排更频繁。

正确的随机播放将在第一遍中从0到N-1选择一个随机数,然后下一个0到N-2等,最后是0到1.这样就会有N!可能的结果,每种可能的排列(假设您正确进行了交换)。