使用 Javascript,我如何生成偏向分布的一端或另一端的随机数?或者理想情况下是范围内的一个点?
对于上下文:我正在创建一个使用随机灰色正方形网格的 UI。我正在使用生成灰色的 RGB 值,Math.random()
但希望能够使灰色平均变暗或变亮,同时仍能代表从黑色到白色的全范围。
(我认为这是一个类似于将java random number generation 向某个数字倾斜的问题,但我正在使用 Javascript ......)
非常感谢任何帮助。
使用 Javascript,我如何生成偏向分布的一端或另一端的随机数?或者理想情况下是范围内的一个点?
对于上下文:我正在创建一个使用随机灰色正方形网格的 UI。我正在使用生成灰色的 RGB 值,Math.random()
但希望能够使灰色平均变暗或变亮,同时仍能代表从黑色到白色的全范围。
(我认为这是一个类似于将java random number generation 向某个数字倾斜的问题,但我正在使用 Javascript ......)
非常感谢任何帮助。
提高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”。)
这似乎比@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 的回答有点,呃,更优雅!
[这可能是一个有点不同的方法。]
这种方法处理以下列方式获取数字:
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
}