簡體   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