4

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

对于上下文:我正在创建一个使用随机灰色正方形网格的 UI。我正在使用生成灰色的 RGB 值,Math.random()但希望能够使灰色平均变暗或变亮,同时仍能代表从黑色到白色的全范围。

(我认为这是一个类似于将java random number generation 向某个数字倾斜的问题,但我正在使用 Javascript ......)

非常感谢任何帮助。

4

3 回答 3

11

提高Math.random()幂以获得伽马曲线- 这会改变 0 和 1 之间的分布,但 0 和 1 保持不变的端点。

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

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

于 2012-07-08T12:57:33.943 回答
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 的回答有点,呃,更优雅!

于 2012-07-08T13:17:54.997 回答
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

}
于 2012-07-08T13:44:19.630 回答