[英]Scrambling characters in Javascript string, are all possible permutations equally likely?
我目前正在研究一个简单的函数,该函数将打乱输入的字符串,其中所有可能的排列都具有相同的可能性。 我的代码如下。
function scramble(s) {
result = s.split("");
for(var i = 0; i < s.length; i++) {
var j = Math.floor(Math.random() * (i + 1));
var scrambler = result[i];
result[i] = result[j];
result[j] = scrambler;
}
return result.join("");
}
到目前为止,代码似乎运行良好……但是所有可能的排列是否都一样? (我相信 Math.random 和 Math.floor,但是当我在运行时查看 i 和 j 时,我得到了奇怪的输出。)
除非我在这里有一个可怕的错误(请检查它是否有意义),否则我相信这段代码不会创建均匀分布的排列。
检查例如第一个字符保持原位的可能性 - 当 i 为 0 时,它不能被任何人替换,当 i 为 1 时,元素 0 和 1 将有 50% 的机会交换,依此类推。 所以总的来说, result[0] 将以1/2 * 2/3 * 3/4 ... n-1/n = 1/n
概率留在它的位置
但是,最后一个元素留在原地的概率只是 (n-1)/n,因为您只有一次机会交换它并且您可以从整个数组中进行选择。
如果将(i+1)
替换为s.length
,则可能会获得更好的分布,但最好的办法是采用已知有效的方法。 你可以从这里开始 - http://en.wikipedia.org/wiki/Random_permutation
Deep necro-posting 因为我有一个类似的问题,这是搜索时的第一个结果。 我的直觉反应与其他回复相同,但在更仔细地查看后, OPs 解决方案似乎是 Fisher-Yates 的有效变体。
让我们来看一个使用 OP 实现的示例。
假设 S = [1,2,3,4]。
第一次迭代:i === 0,j 必须等于 0。不进行任何交换。 你可以跳过这个循环。
第二次迭代:i === 1,j 可以是 0 或 1。
[1,2,3,4] (j === 1, no swap so same as original),
[2,1,3,4] (j === 0, swap),
请注意,[0-1] 导致 0,1 的所有变化的概率相等
第三次迭代:i === 2,j 可以等于 0,1,2。
[1,2,3,4], [2,1,3,4] (j === 2, no swap so same as previous results),
[1,3,2,4], [2,3,1,4] (j === 1, swaps),
[3,2,1,4], [3,1,2,4] (j === 0, swaps),
请注意,[0-2] 导致 0,1,2 的所有变化的概率相等
第四次迭代:i === 3,j 可以等于 0、1、2、3。
[1,2,3,4], [2,1,3,4], [1,3,2,4], [2,3,1,4], [3,2,1,4], [3,1,2,4] (j === 3, no swap so same as previous results),
[1,2,4,3], [2,1,4,3], [1,3,4,2], [2,3,4,1], [3,2,4,1], [3,1,4,2] (j === 2, swaps),
[1,4,3,2], [2,4,3,1], [1,4,2,3], [2,4,1,3], [3,4,1,2], [3,4,2,1] (j === 1, swaps),
[4,2,3,1], [4,1,3,2], [4,3,2,1], [4,3,1,2], [4,2,1,3], [4,1,2,3] (j === 0, swaps),
再次注意,结果是字符串的所有排列等概率!
这样做的原因与链接维基中描述的“现代算法”非常相似
for i from n−1 down to 1 do
j ← random integer such that 0 ≤ j ≤ i
exchange a[j] and a[i]
Op 对每个元素执行相同的操作(j 设置在 0 和 i 之间),并以相反的方向循环。 每个元素的交换是先完成还是最后完成都不会改变结果。
OP 实现和 Fisher Yates 都分享了@leeor 发布的推理陷阱。 即使元素被交换的概率越来越小,但每个元素被交换到每个位置的概率是相等的,从而得到我们想要的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.