不同范围的随机数概率不同

4
我正在寻找实现随机数生成器的最佳方法,它将允许我控制从哪个范围返回生成的数字的概率。为了展示我想要实现的内容,这里有一张图片: 不均匀随机分布 所以总结一下: 假设我的范围是400。一开始,我想要获得5%的概率得到0-20的数字。但是在某个时刻,我希望这个概率增加到50%。希望你能明白我的意思。

1
我希望默认情况下,获得0-20范围内的数字概率为5%。将其增加到50%意味着每隔一秒钟请求一次0-20范围内的数字,另外的时间请求21-400范围内的数字。你目前有什么进展? - RobG
只是在寻找一个想法。好的,但如果我想让它变成16%呢? - sasklacz
2个回答

3

我觉得你需要的是一种生成正态分布(或高斯分布)数字的方法(如果你不知道这是什么,请看维基百科页面)。

Box-Muller变换可以用于生成成对的正态分布数字。

这里是极坐标形式的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++类,你可以在Rick Wagner的页面中找到它。你可以在此页面上找到有关Box-Muller变换的更多有用信息。


乍一看,这似乎正是我正在寻找的东西。 - sasklacz

3

嗯,根据您的原始内容,我有一个非常简单的算法来按比例生成数组中的范围,然后随机选择一个范围并在该范围内生成随机数。毫无疑问,如果需要,它可以进行优化,但对我而言它很有效。

看起来代码很多,但其中3/4是注释、测试数据和函数,实际的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 = [...]之后缺少分号;。但这很棒!非常感谢您的分享。 - Ilyssis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接