我正在寻找实现随机数生成器的最佳方法,这将允许我控制从生成的数字返回的范围内的概率。为了想象我想要实现的目标,我有一张图片:
总结一下: 假设我的范围是400.一开始我想有5%的概率获得0-20。但在某个时刻,我希望这个概率增加到50%。希望你明白这一点。
答案 0 :(得分:3)
听起来像你正在寻找的是一种在普通(或高斯)分布上生成数字的方法(如果你不知道这意味着什么,请看the Wikipedia page。)< / p>
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转换的更多有用信息。
答案 1 :(得分: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>