【问题标题】:Different probability for ranges of random numbers随机数范围的不同概率
【发布时间】:2011-08-26 21:13:13
【问题描述】:

我正在寻找实现随机数生成器的最佳方法,这将使我能够控制从哪个范围内生成的数字将被返回的概率。为了形象化我想要实现的目标,我有一张图片:

总结一下: 假设我的范围是 400。一开始我希望有 5% 的概率获得数字 0-20。但在某个时刻,我希望将这个概率提高到 50%。希望你能明白。

【问题讨论】:

  • 我希望获取 0-20 范围内的数字默认为 5%。将其增加到 50% 仅意味着每秒要求 0-20 范围内的数字,其他时间要求 21-400 范围内的数字。到目前为止你有什么?
  • 只是在寻找一个想法。好的,但是如果我希望它是 16% 呢?

标签: javascript random distribution probability


【解决方案1】:

嗯,在处理您的原始文件时,我有一个非常简单的算法,可以以适当的比例在数组中生成范围,然后随机选择一个范围并在该范围内生成一个随机数。毫无疑问,它可以在必要时进行优化,但它对我有用。

看起来代码很多,但其中3/4是cmets、测试数据和函数,实际randomRange函数只有17行代码。

<script type="text/javascript">

function randomRange(dataArray) {

  // Helper function
  function getRandomInRange(s, f) {
    return (Math.random() * (f-s+1) | 0) + s
  }

  // Generate new data array based on probability
  var i, j = dataArray.length;
  var oArray = [];
  var o;
  while (j--) {
    o = dataArray[j];

    // Make sure probability is an integer
    for (i=0, iLen=o.probability|0; i<iLen; i++) {  
      oArray.push([o.rangeStart, o.rangeEnd]);
    }
  }

  // Randomly select a range from new data array and
  // generate a random number in that range
  var oEnd = oArray.length;
  var range = oArray[getRandomInRange(0, oArray.length - 1)]; 
  return getRandomInRange(range[0], range[1]);
}

// Test data set. Probability just has to be
// representative, so 50/50 === 1/1
var dataArray = [
  {
    rangeStart: 0, 
    rangeEnd  : 20,
    probability: 1
  },
  {
    rangeStart: 21, 
    rangeEnd  : 400,
    probability: 1
  }
];

// Test function to show range and number is randomly
// selected for given probability
function testIt() {
  var el0 = document.getElementById('div0');
  var el1 = document.getElementById('div1');
  function run() {
    var n = randomRange(dataArray);
    if (n <= 20) {
      el0.innerHTML += '*';
    } else {
      el1.innerHTML += '*';
    }
  }
  setInterval(run, 500);
}


</script>

<button onclick="testIt();">Generate random number</button>

<div>Numbers 0 - 20</div>
<div id="div0"></div>
<div>Numbers 21 - 400</div>
<div id="div1"></div>

【讨论】:

  • 缺少分号;在 var dataArray = [...] 之后(如果您正在使用代码缩小)。但这是一个伟大的人!非常感谢分享这个。
【解决方案2】:

在我看来,您正在寻找的是一种在正态(或高斯)分布上生成数字的方法(如果您不知道这意味着什么,请查看 the Wikipedia page)。

Box-Muller transformation 可用于生成正态分布数对。

这里是 Box-Muller 转换的极坐标形式的 c++ 实现,应该不难翻译成 javascript。

// Return a real number from a normal (Gaussian) distribution with given
// mean and standard deviation by polar form of Box-Muller transformation
double x, y, r;
do
{
    x = 2.0 * rand() - 1.0;
    y = 2.0 * rand() - 1.0;
    r = x * x + y * y;
}
while ( r >= 1.0 || r == 0.0 );
double s = sqrt( -2.0 * log(r) / r );
return mean + x * s * stddev;

其中mean是正态分布的平均值,stddev是分布的标准差。这段代码来自我最近一直在使用的 MersesenneTwister C++ 类,您可以找到 on Rick Wagner's page。您可以在 this page 上找到有关 Box-Muller 转换的更多有用信息。

【讨论】:

  • 乍一看就像我要找的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
  • 2019-08-11
  • 2019-05-18
  • 1970-01-01
  • 2013-05-02
相关资源
最近更新 更多