我应该如何在 O(1) 中映射连续随机变量



给定 [0, 1] 中均匀分布的随机数),如何根据该数字所在的区域映射结果?这是一个天真的解决方案,其中包含我的 jsfiddle 中的片段:

function mapRandomNumber(){
    var randomNumber = Math.random();
    if(randomNumber < 0.2){ // 20%
        return 0;
    } else if(randomNumber < 0.3){ // 10%
        return 1;
    } else if(randomNumber < 0.5){ // 20%
        return 2;
    } else if(randomNumber < 0.65){ // 15%
        return 3;
    } else if(randomNumber < 0.9){ // 25%
        return 4;
    } else { // 10%
        return 5;
    }
}

但是,如果我有数十个或数百个病例怎么办?这将意味着数十个和数百个if-else,这并不优雅且难以修改。

对于简单情况(对于有理概率),一个O(1)答案是取随机数,将其离散化,并映射这些结果。下面是一个包含 3 个数字的示例:

numberMap = {
    0: 0, // 1/3%
    1: 0, // 1/3%
    2: 1 // 1/3%
}
function mapRandomNumber(){
    var randomNumber = Math.random(); // [0, 1)
    randomNumber = randomNumber*3; // [0, 3)
    randomNumber = Math.floor(randomNumber); // 0 or 1 or 2
    // returns zero 2/3 of the time, and returns one 1/3 of the time
    return numberMap[randomNumber];
}

这并不真正适用于无理概率,并且对于许多映射应返回相同结果的大型地图可能效率低下。

我更喜欢任何具有恒定时间复杂度(O(1))的编程语言的通用解决方案。

var limits = [
    0.001,
    0.01,
    0.1,
    0.3,
    0.30001,
    0, // this deletes this index from the output
    0.7,
    0.9,
    1];
function mapNumber(num) {
    for (var i=0; i<limits.length; i++) {
        if (num <= limits[i])
            // here we simply map to the index, but the values in the limits
            // array could also be used to store the mapping value.
            return i;
    }
}
console.log(mapNumber(0)); // 0
console.log(mapNumber(0.000000001)); // 0
console.log(mapNumber(0.015)); // 2
console.log(mapNumber(0.4)); // 6

最新更新