Question

Using Node.js we are trying to come up with a way of generating a random number that falls between 1 and 100. However instead of using a standard linear distribution like the typical RAND() function might we want to instead use a Weibull (or some such) distribution that will give a long tail and weigh the answers more heavily toward the larger values - for example a value of 75 to 100 might be generated 80% of the time, a value of 50 to 74 would be generated 15% of the time, and the remainder (< 20) generated 5% of the time.

We have found a Weibul random variable function using the following formula alpha*(-ln(1-X))^(1/beta). Assuming X is a standard linear random from 0 to 1, using alpha = 1, and a beta <= 1 seems to give us a good distribution, however we are stumped as to how to generate a single value that will always fall between 1 and 100.

Any ideas or recommendations are appreciated.

Was it helpful?

Solution

Ok - just in case anyone is interested in my version of an answer. Using the following reference got me to my goal of constraining the Weibull result set:

https://stats.stackexchange.com/questions/30303/how-to-simulate-data-that-satisfy-specific-constraints-such-as-having-specific-m

The following links were also handy:

http://en.wikipedia.org/wiki/Weibull_distribution

http://mathworld.wolfram.com/WeibullDistribution.html

In the end my roughed in node,js code looks like this:

var desiredMin = 1; //the desired minimum random result 
var desiredMax = 50; //the desired maximum random result 
var scale = 1; //Weibul scale parameter (1 provides an inverse result set)
var shape = 10; //Weibul shape parameter (how skewed the result set is)

//given an possible random range of {0,1} value calculate the minimum and maximum Weibull distribution values given current shape and scale parameters
var weibullMin = Math.pow((shape*scale), (-1*shape)) * Math.pow(.000001, shape -1) * Math.exp(Math.pow((.000001/scale), shape));
var weibullMax = Math.pow((shape*scale), (-1*shape)) * Math.pow(.999999, shape -1) * Math.exp(Math.pow((.999999/scale), shape));

//simulate 1000 random weibull values and write results to file
fileStream.once('open', function(fd) {
    for(var i = 1; i <= 1000; i++) {
        var r = Math.random();
        var weibullRandom = Math.pow((shape*scale), (-1*shape)) * Math.pow(r, shape-1) * Math.exp(Math.pow((r/scale), shape)); //generate Weibull random value
        var weibullRandomAdjusted = desiredMin + (desiredMax - desiredMin)*((weibullRandom-weibullMin) / (weibullMax - weibullMin)); //adjust Weibull random value so that it constrained into the desired min/max range
        fileStream.write(weibullRandomAdjusted + "\n");
    };
    fileStream.end();
});

I've run the code for varying 'shape' values and it is providing me exactly the results I need.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top