繁体   English   中英

从任意加权列表生成随机数

[英]Generate random number from an arbitrary weighted list

这是我需要做的,我将同时在PHP和JavaScript中进行操作。

我有一个数字列表,范围从1到300-500(我尚未设置限制)。 我将运行一个绘图,将从给定范围内随机选取10个数字。

这是棘手的部分:我希望一些数字不太可能被绘制出来。 一小部分300-500将被标记为“幸运数字”。

例如,在100张图纸中,除少数几个以外,大多数数字都有相等的被抽奖机会,每30-50张图纸中只能抽奖一次。

基本上,我需要人为设置某些数字的概率,同时保持与其他数字的均匀分布。

到目前为止,我发现的唯一类似问题是: 生成加权随机数 ,问题是我的规范中有很多数字(最多500个),因此权重会变得很小,并且可能这可能是一个问题该解决方案(拒绝采样)。 虽然我仍在尝试,但是我想知道是否还有其他解决方案。

数学不是我的事,所以我感谢任何投入。 谢谢。

我写了一个简短的JSFiddle来处理这个问题:

http://jsfiddle.net/cHVsC/

基本上,我生成一个称为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM