[英]Generate random number from an arbitrary weighted list
这是我需要做的,我将同时在PHP和JavaScript中进行操作。
我有一个数字列表,范围从1到300-500(我尚未设置限制)。 我将运行一个绘图,将从给定范围内随机选取10个数字。
这是棘手的部分:我希望一些数字不太可能被绘制出来。 一小部分300-500将被标记为“幸运数字”。
例如,在100张图纸中,除少数几个以外,大多数数字都有相等的被抽奖机会,每30-50张图纸中只能抽奖一次。
基本上,我需要人为设置某些数字的概率,同时保持与其他数字的均匀分布。
到目前为止,我发现的唯一类似问题是: 生成加权随机数 ,问题是我的规范中有很多数字(最多500个),因此权重会变得很小,并且可能这可能是一个问题该解决方案(拒绝采样)。 虽然我仍在尝试,但是我想知道是否还有其他解决方案。
数学不是我的事,所以我感谢任何投入。 谢谢。
我写了一个简短的JSFiddle来处理这个问题:
基本上,我生成一个称为pool
的数组,其中包含数字的完整列表,包括权重较大的数字的重复项。 然后,选择将与非加权数组完全一样进行。
样本JS:
function generatePool (count, luckyNumbers) {
var arr = [], i, j;
for (i = 1; i <= count; i++) {
if (luckyNumbers[i]) {
for (j = 0; j < luckyNumbers[i]; j++) {
arr.push(i);
}
} else {
arr.push(i);
}
}
return arr;
}
function randomNumber (pool) {
return pool[ Math.floor(Math.random() * pool.length) ];
}
和用法示例
var luckyNumbers = {};
luckyNumbers[13] = 10;
luckyNumbers[25] = 100;
var pool = generatePool(300, luckyNumbers);
alert(randomNumber(pool));
更新:我误解了最初的目标。 这是更新的版本:
function generatePool (count, luckyNumbers) {
var arr = [], i, j;
for (i = 1; i <= count; i++) {
for (j = 0; j < (luckyNumbers[i] || 10); j++) {
arr.push(i);
}
}
return arr;
}
function randomNumber (pool) {
return pool[ Math.floor(Math.random() * pool.length) ];
}
一个用法示例:
var luckyNumbers = {};
luckyNumbers[13] = 1; //-- ~1:10 odds
luckyNumbers[25] = 2; //-- ~2:10 odds
var pool = generatePool(300, luckyNumbers);
console.log(randomNumber(pool));
function pick_number() {
$lucky_numbers = range(1,10);
$regular_numbers = range(11,100);
//pick lucky numbers with 30% probability
//even though they only represent 10% of all numbers
if(rand(1,100) <= 30) {
$index = rand(0,count($lucky_numbers)-1);
$number = $lucky_numbers[$index];
}
else {
$index = rand(0,count($regular_numbers)-1);
$number = $regular_numbers[$index];
}
return $number;
}
$frequency = [];
foreach(range(1,1000) as $i) {
$frequency[pick_number()]++;
}
ksort($frequency);
print_r($frequency);
OUTPUT
Array
(
[1] => 27
[2] => 31
[3] => 31
[4] => 37
[5] => 25
[6] => 37
[7] => 33
[8] => 20
[9] => 34
[10] => 33
[11] => 7
[12] => 11
[13] => 11
[14] => 9
[15] => 13
[16] => 9
[17] => 13
[18] => 5
[19] => 4
[20] => 6
[21] => 9
[22] => 3
[23] => 4
[24] => 9
[25] => 6
[26] => 10
[27] => 2
[28] => 10
[29] => 14
[30] => 7
[31] => 7
[32] => 3
[33] => 13
[34] => 8
[35] => 14
[36] => 8
[37] => 8
[38] => 3
[39] => 13
[40] => 12
[41] => 7
[42] => 7
[43] => 8
[44] => 4
[45] => 8
[46] => 10
[47] => 7
[48] => 5
[49] => 5
[50] => 6
[51] => 9
[52] => 7
[53] => 14
[54] => 12
[55] => 4
[56] => 9
[57] => 4
[58] => 8
[59] => 1
[60] => 9
[61] => 14
[62] => 8
[63] => 13
[64] => 4
[65] => 4
[66] => 10
[67] => 11
[68] => 7
[69] => 7
[70] => 8
[71] => 4
[72] => 4
[73] => 6
[74] => 6
[75] => 10
[76] => 6
[77] => 10
[78] => 4
[79] => 10
[80] => 9
[81] => 5
[82] => 8
[83] => 7
[84] => 8
[85] => 8
[86] => 6
[87] => 10
[88] => 8
[89] => 5
[90] => 6
[91] => 8
[92] => 2
[93] => 8
[94] => 4
[95] => 8
[96] => 5
[97] => 6
[98] => 12
[99] => 11
[100] => 7
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.