Skip to content Skip to sidebar Skip to footer

How To Generate Skewed Random Numbers In Javascript?

Using Javascript, how can I generate random numbers that are skewed towards one end or the other of the distribution? Or ideally an point within the range? For context: I'm creatin

Solution 1:

Raise Math.random() to a power to get a gamma curve - this changes the distribution between 0 and 1, but 0 and 1 stay constant endpoints.

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

For gamma>1, you will get darker output; for 0<gamma<1 you get lighter. (Here, '2' gives you the x-squared curve; the equidistant lightness would be '0.5' for the square-root curve.)

Solution 2:

This seems a little crude and less graceful than @bobince's answer, but what the hell.

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

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

    //generate random greyvar 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);

Essentially it generates random greys then decides, based on probably specified (as a percentage) in skew_chance, whether to skew it or not. (In case you wanted to make this occasional, not constant). If it decides to skew, a random number is then added or subtracted from the grey value (depending on whether the skew endpoint is under or above the current value).

This random number is a number between 0 and the absolute difference between the current value and the endpoint, e.g. if current value is 40, and the endpoint is 100, the number added would be between 0 and 60.

Like I say, @bobince's answer is somewhat, er, more graceful!

Solution 3:

[This might be a little different approach.]

This approach deals with getting the number in the following fashion:

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

Where:

  • numberToSkewTo is the number you want to skew towards.
  • stdDeviation is the deviation from numberToSkewTo
  • numberToSkewTo + abs(stdDeviation) <= MAX_NUMBER and
  • numberToSkewTo - abs(stdDeviation) >= MIN_NUMBER

What the following code does is, it pick a random number around the given number with constantly increasing standard deviations. It returns the average of results.

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

functiongetRandom(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

}

Post a Comment for "How To Generate Skewed Random Numbers In Javascript?"