如何在Javascript中生成偏斜的随机数?

时间:2012-07-08 12:42:01

标签: javascript math random

使用Javascript,如何生成偏向一端或另一端的随机数?或理想情况下该范围内的一点?

对于上下文:我正在创建一个使用随机灰色方块网格的UI。我正在使用Math.random()生成灰色的RGB值,但是希望能够将灰色倾斜为平均更暗或更亮,同时仍然具有从黑到白的全范围。

(我认为这是与Skewing java random number generation toward a certain number类似的问题,但我正在使用Javascript ...)

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:11)

Math.random()提升为获得gamma curve的权力 - 这会改变0到1之间的分布,但0和1保持不变的端点。

var r= Math.pow(Math.random(), 2);
var colour= 'rgb('+r*255+', '+r*255+', '+r*255+')';

对于gamma> 1,您将获得更暗的输出;对于0 <γ<1,你变得更轻。 (这里,'2'给出x平方曲线;平方根曲线的等距亮度为'0.5'。)

答案 1 :(得分:2)

这看起来有点粗糙,不如@ bobince的回答那么优雅,但到底是怎么回事。

//setup
var colours = [], num_colours = 10, skew_to = 255, skew_chance = 20;

//get as many RGB vals as required
for (var i=0; i<num_colours; i++) {

    //generate random grey
    var this_grey = Math.floor(Math.random() * 256);

    //skew it towards the @skew_to endpoint, or leave as-is?
    if (Math.floor(Math.random() * 100) >= skew_chance && this_grey != skew_to) {

            //skew by random amount (0 - difference between curr val and endpoint)
        var skew_amount = Math.floor(Math.random() * Math.abs(this_grey - skew_to));
        this_grey += ' (skewed to '+(skew_to < this_grey ? this_grey - skew_amount : this_grey + skew_amount)+')';
    }
    colours.push(this_grey);
}
console.log(colours);

基本上它会生成随机灰色,然后根据skew_chance中可能指定的(以百分比形式)决定是否倾斜。 (如果你想偶尔做这个,不是常数)。如果它决定倾斜,则在灰度值中加上或减去一个随机数(取决于偏斜终点是否低于或高于当前值)。

该随机数是介于0和当前值与端点之间的绝对差值之间的数字,例如,如果当前值为40,并且端点为100,则添加的数字将介于0和60之间。

就像我说的那样,@ bobince的答案有点,呃,更优雅!

答案 2 :(得分:1)

[这可能是一个不同的方法。]

此方法涉及以下列方式获取数字:

random = numberToSkewTo + random(-1,1)*stdDeviation

其中:

  • numberToSkewTo是您想要偏向的数字。
  • stdDeviation是与numberToSkewTo
  • 的偏差
  • numberToSkewTo + abs(stdDeviation) <= MAX_NUMBER
  • numberToSkewTo - abs(stdDeviation) >= MIN_NUMBER

以下代码的作用是,它在给定数字周围选择一个随机数,并且标准偏差不断增加。它返回结果的平均值。

function skew(skewTo,stdDev){
    var rand = (Math.random()*2 - 1) + (Math.random()*2 - 1) + (Math.random()*2 - 1);
    return skewTo + rand*stdDev;
}

function getRandom(skewTo){
    var difference = Math.min(skewTo-MIN_NUMBER, MAX_NUMBER-skewTo);
    var steps = 5;
    var total = 0.0;
    for(var i=1; i<=steps; i++)
        total += skew(skewTo, 1.0*i*difference/steps);
    return total/steps

}