我目前正在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,因为我是一名全新的程序员并且对此更加满意。:)
答案 0 :(得分:0)
非常简单的数学。如果你从整个集合中切换另一个元素,你最终会得到一个从0到N-1,N次的随机数,所以有N ** N个可能的结果。既然有N! (即阶乘N)项目的可能安排,N ** N不能被N!整除,某些安排会比其他安排更频繁。
正确的随机播放将在第一遍中从0到N-1选择一个随机数,然后下一个0到N-2等,最后是0到1.这样就会有N!可能的结果,每种可能的排列(假设您正确进行了交换)。