下面是JS中随机整数生成的一个非常简单的示例,其中我丝毫不“拉伸极限”。
我只能从10 ^ 6很大的空间中生成500个唯一的随机整数。
但是,如果您继续单击该按钮,则偶尔会在500个中看到499或498个唯一的按钮。它的发生频率不是很高,但是可能每单击10或15次就会发生一次。这是为什么?我的空间是一百万。我不希望在第10次或第20次点击的频率下发生500次采样的碰撞。
要进行测试,请继续单击按钮并观看控制台。
function run() {
var nums = new Set();
for (var i = 0; i < 500; i++) {
nums.add(randomInteger10to6th());
}
console.clear();
console.log('Random 10^6 Unique Integer set: ' + nums.size);
}
function randomInteger10to6th() {
return Math.round(Math.random() * Math.pow(10,6))
}
<button id="run" onclick="run();">Run 500 Random Integers, Space: 10^6</button>
答案 0 :(得分:9)
当您从1-1e6中选择500个随机数时,看到所有唯一数字的概率可以计算如下: 1e6 / 1e6 * 999,999 / 1e6 * 999,998 / 1e6 * ... * 999,501 / 1e6
这大约是0.88
这意味着超过10%的时间,您将在500个随机变量的列表中至少有一个重复项。
您可以在下面的代码段中对100个实验进行验证:
function run() {
var nums = new Set();
for (var i = 0; i < 500; i++) {
nums.add(randomInteger10to6th());
}
return nums;
}
function randomInteger10to6th() {
return Math.round(Math.random() * Math.pow(10, 6))
}
// perform 100 experiments and see how many have duplicates
var uniques = 0, collisions = 0;
for (var i = 0; i < 100; i++) {
var nums = run();
if (nums.size === 500) uniques++;
else collisions++;
}
console.log('Runs that generated unique numbers', uniques);
console.log('Runs that resulted in collisions', collisions);
答案 1 :(得分:1)
“随机”仅表示:它是随机的。不管之前选择了什么,范围内的每个值都具有相同的被选择概率。因此,即使选择了数字5,它仍然有再次选择5的机会与选择任何其他数字的机会相同。您不应该期望随机数会避免重复-如果重复的话,它们就不会是随机的:)
答案 2 :(得分:1)
由于您要从大量样本中生成相对较少的随机数,因此您应该能够在碰撞时重新生成新数。添加随机数直到达到500,都会导致对随机数生成器的一些额外调用,但这将保证500个唯一数字:
function run() {
var nums = new Set();
while (nums.size < 500){
nums.add(randomInteger10to6th());
}
console.clear();
console.log('Random 10^6 Unique Integer set: ' + nums.size);
}
function randomInteger10to6th() {
return Math.round(Math.random() * Math.pow(10,6))
}
<button id="run" onclick="run();">Run 500 Random Integers, Space: 10^6</button>
答案 3 :(得分:0)
您也可以使用简单数组代替Set()
。首先,创建包含500个索引的数组,然后填充它。
function run() {
/* first create an array with 500 slots, then fill it with
undefined ( fill() without args is undefined ). For the
last step map through 500 slots of undefined and overwrite
it with a random number */
return new Array(500).fill().map(x => Math.round(Math.random() * Math.pow(10,6)))
}
console.log(run().length)
<button id="run" onclick="run();">Run 500 Random Integers, Space: 10^6</button>
如果您想删除重复项,则只需将它们过滤掉即可重新计算。
function run() {
// same like the upper function but with a duplicates filter
let arrayWithNumbers = new Array(500).fill().map(x => Math.round(Math.random() * Math.pow(10,6))).filter((item, idx, self) => self.indexOf(item) == idx)
// run again if array less than 500
if(arrayWithNumbers.length !== 500) {
run()
}
return arrayWithNumbers
}
console.log(run().length)
<button id="run" onclick="run();">Run 500 Random Integers, Space: 10^6</button>