【问题标题】:How should I map a continuously random variable in O(1)?我应该如何在 O(1) 中映射一个连续随机变量?
【发布时间】:2014-02-26 21:55:25
【问题描述】:

给定 [0, 1) 中的均匀分布随机数,我如何根据该数字所在的区域映射结果?这是一个来自my jsfiddle 的带有sn-p 的简单解决方案:

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)) 的编程语言,我更喜欢通用解决方案。

【问题讨论】:

  • 这是一道作业题吗?
  • parseInt() 不适用于将浮点数转换为整数。在这里使用Math.floor()
  • 您是否考虑过制定一组限制,而不是离散您的频谱并制作地图?
  • 这不是作业问题。这是针对个人项目的,我需要有效地生成大量随机数。是的,我会使用 Math.floor。
  • Squid,如何在没有条件的情况下以编程方式设置一组限制?有没有不使用条件的方法?

标签: javascript random map statistics probability


【解决方案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

【讨论】:

  • 这实际上与我的第一个解决方案相同,只是稍微清理了一下。这里的问题是仍在使用条件语句,这会占用 cpu。如果我有 1000 万个“限制”,那么在最坏的情况下,我必须执行 1000 万个 if 语句来查看我的随机数是否落在最后一个区域。我想避免这种情况。
  • 如果您知道您的限制列表已排序(或者如果您对其进行了排序),那么您可以使用各种算法来避免线性行为。 Binary search 浮现在脑海中。平均而言,它将您的测试数量从n/2 减少到log_2(n)。试一试,一两次尝试后如果需要帮助,请告诉我。
  • 我澄清了包含 O(1) 的问题。这就是我说映射随机变量时的意思。我对非 O(1) 解决方案不感兴趣。
  • 如果你必须有恒定的时间,使用你建议的桶方法很可能是唯一的选择(假设你可以处理连续性的损失)。我不记得有任何合理的算法可以在恒定时间内做你想做的事,但我不是算法专家,所以我可能根本不知道。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-06
  • 2015-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多