为什么需要多次尝试才能生成 1 到 10000 之间的随机值?



我有以下代码,它生成一个介于 1 和 10000 之间的初始随机数,然后重复生成第二个随机数,直到它与第一个随机数匹配:

let upper = 10000;
let randomNumber = getRandomNumber(upper);
let guess;
let attempt = 0;
function getRandomNumber(upper) {
return Math.floor(Math.random() * upper) + 1;
}
while (guess !== randomNumber) {
guess = getRandomNumber(upper);
attempt += 1;
}
document.write('The randomNumber is ' + randomNumber);
document.write(' it took' + attempt);

我对(尝试)变量感到困惑。为什么计算机需要这么多次尝试才能获得randomNumber? 此外,它没有将尝试置于循环条件。

只是为了给你一个开始。这是您的代码的作用:

// define the maximum of randomly generated number. range = 0 - 10.000
let upper = 10000;
// generate a random number out of the range 0-10.000
let randomNumber = getRandomNumber(upper);
// predefine variable guess
let guess;
// set a counter to 0
let attempt = 0;
// generate and return a random number out of the range from 0 to `upper`
function getRandomNumber(upper) {
return Math.floor(Math.random() * upper) + 1;
}
// loop until guess equals randomNumber
while (guess !== randomNumber) {
// generate a new random number and assign it to the variable guess
guess = getRandomNumber(upper);
// increase the counter by 1
attempt += 1;
}
// output the initially generated number
document.write('The randomNumber is ' + randomNumber);
// output the number of repetitions
document.write(' it took' + attempt);

所以,再一次。在开始时生成一个随机数。然后重复生成另一个随机数,直到第二个随机数与第一个随机数匹配。由于您没有设置任何限制,例如"每个随机数只能出现一次"或"不超过 10.000 次尝试",您的程序可能需要数百万次尝试,直到数字匹配,因为您有 10.000 个可能的数字的范围,它们可能会在匹配最终出现之前重复数百次。

尝试通过将尝试次数限制为 10.000 来优化程序。你可以让你的电脑从0到10.000向上计数,而不是用随机生成的数字来猜测。

当我反复运行您的代码片段时,我看到您的代码需要几千到几万次重复才能获得 1 到 10000 之间采样的随机数的给定值。 但这并不奇怪 -这是意料之中的。

假设您的getRandomNumber(upper)函数确实返回了一个介于1upper之间的均匀分布的数字,则返回的数字不是初始值的预期概率randomNumber为:

1 - (1/upper)

第一个N生成的数字不包括给定值的可能性是:

(1 - (1/upper)) ^ N

因此,PN生成的数字包含给定值的几率是:

P = 1 - (1 - (1/upper)) ^ N

因此,以下公式给出了生成具有给定概率P初始值所需的重复次数:

N = ln(1.0 - P) / ln(1.0 - (1.0/upper))

使用此公式,在 6932 次重复后只有 50% 的机会获得randomValue,在 29956 次重复后有 95% 的机会>

let upper = 10000;
function numberOfRepetitionsToGetValueWithRequiredProbability(upper, P) {
return Math.ceil(Math.log(1.0 - P) / Math.log(1.0 - (1.0/upper)))
}
function printNumberOfRepetitionsToGetValueWithRequiredProbability(upper, P) {
document.write('The number of tries to get a given value between 1 and ' + upper + ' with a ' + P + ' probability: ' + numberOfRepetitionsToGetValueWithRequiredProbability(upper, P) + ".<br>");     
}
var probabilities = [0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 0.95, 0.99, 0.9999];
probabilities.forEach((p) => printNumberOfRepetitionsToGetValueWithRequiredProbability(upper, p));
<。

这与观察到的代码行为完全一致。 当然,假设Math.random()真的是随机的(根据文档,它不是,它只是伪随机的),无论你重复多少次,总会有很小的概率永远不会遇到你的初始值。

最新更新