Different probability for ranges of random numbers

I am looking for the best way to implement a random number generator that will allow me to control the probability of which range the generated number will be returned from. To visualize what I'm trying to achieve, I have a photo:

not uniform random distribution

So, to summarize: Let's say that my range is 400. First, I would like to have a 5% chance of getting the number 0-20. But at some point I would like this probability to increase to 50%. I hope you understand this idea.

+4
source share
2 answers

Hmm, working on your original, I had a fairly simple algorithm to create ranges in an array in the appropriate proportion, then randomly select a range and generate a random number in that range. Without a doubt, if necessary, it can be optimized, but it works for me.

It looks like a lot of code, but 3/4 of its comments, test data and functions, the actual randomRange function is only 17 lines of code.

<script type="text/javascript"> function randomRange(dataArray) { // Helper function function getRandomInRange(s, f) { return (Math.random() * (f-s+1) | 0) + s } // Generate new data array based on probability var i, j = dataArray.length; var oArray = []; var o; while (j--) { o = dataArray[j]; // Make sure probability is an integer for (i=0, iLen=o.probability|0; i<iLen; i++) { oArray.push([o.rangeStart, o.rangeEnd]); } } // Randomly select a range from new data array and // generate a random number in that range var oEnd = oArray.length; var range = oArray[getRandomInRange(0, oArray.length - 1)]; return getRandomInRange(range[0], range[1]); } // Test data set. Probability just has to be // representative, so 50/50 === 1/1 var dataArray = [ { rangeStart: 0, rangeEnd : 20, probability: 1 }, { rangeStart: 21, rangeEnd : 400, probability: 1 } ]; // Test function to show range and number is randomly // selected for given probability function testIt() { var el0 = document.getElementById('div0'); var el1 = document.getElementById('div1'); function run() { var n = randomRange(dataArray); if (n <= 20) { el0.innerHTML += '*'; } else { el1.innerHTML += '*'; } } setInterval(run, 500); } </script> <button onclick="testIt();">Generate random number</button> <div>Numbers 0 - 20</div> <div id="div0"></div> <div>Numbers 21 - 400</div> <div id="div1"></div> 
+3
source

It seems to me that what you are looking for is a way to generate numbers in a normal (or Gaussian) distribution (see the Wikipedia page if you don’t know what that means).

The Box-Muller transform can be used to generate pairs of normally distributed numbers.

Here is the C ++ implementation of the Box-Muller polar form conversion, which should not be translated into javascript.

 // Return a real number from a normal (Gaussian) distribution with given // mean and standard deviation by polar form of Box-Muller transformation double x, y, r; do { x = 2.0 * rand() - 1.0; y = 2.0 * rand() - 1.0; r = x * x + y * y; } while ( r >= 1.0 || r == 0.0 ); double s = sqrt( -2.0 * log(r) / r ); return mean + x * s * stddev; 

Where mean means normal distribution and stddev is the standard deviation of the distribution. This code from the MersesenneTwister C ++ class that I used recently can be found on Rick Wagner's page . You can find more useful information about Box-Muller transformation on this page .

+3
source

All Articles