简体   繁体   中英

Influence Math.random()

I'm looking for a way to influence Math.random().

I have this function to generate a number from min to max:

var rand = function(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

Is there a way to make it more likely to get a low and high number than a number in the middle?

For example; rand(0, 10) would return more of 0,1,9,10 than the rest.

Is there a way to make it more likely to get a low and high number than a number in the middle?

Yes. You want to change the distribution of the numbers generated.

http://en.wikipedia.org/wiki/Random_number_generation#Generation_from_a_probability_distribution

One simple solution would be to generate an array with say, 100 elements.

In those 100 elements represent the numbers you are interested in more frequently.

As a simple example, say you wanted number 1 and 10 to show up more frequently, you could overrepresent it in the array. ie. have number one in the array 20 times, number 10 in the array 20 times, and the rest of the numbers in there distributed evenly. Then use a random number between 0-100 as the array index. This will increase your probability of getting a 1 or a 10 versus the other numbers.

You need a distribution map. Mapping from random output [0,1] to your desired distribution outcome. like [0,.3] will yield 0, [.3,.5] will yield 1, and so on.

Sure. It's not entirely clear whether you want a smooth rolloff so (for example) 2 and 8 are returned more often than 5 or 6, but the general idea works either way.

The typical way to do this is to generate a larger range of numbers than you'll output. For example, lets start with 5 as the base line occurring with frequency N. Let's assume that you want 4 or 7 to occur at frequency 2N, 3 or 8 at frequency 3N, 2 or 9 and frequency 4N and 0 or 10 at frequency 5N.

Adding those up, we need values from 1 to 29 (or 0 to 28, or whatever) from the generator. Any of the first 5 gives an output of 0. Any of the next 4 gives and output of 1. Any of the next 3 gives an output of 2, and so on.

Of course, this doesn't change the values returned by the original generator -- it just lets us write a generator of our own that produces numbers following the distribution we've chosen.

Not really. There is a sequence of numbers that are generated based off the seed. Your random numbers come from the sequence. When you call random, you are grabbing the next element of the sequence.

Can you influence the output of Math.random in javascript (which runs client side)?

No. At least not in any feasible/practical manner.

But what you could do is to create your own random number generator that produces number in the distribution that you need.

There are probably an infinite number of ways of doing it, and you might want to think about the exact shape/curvature of the probability function.

It can be probably be done in one line, but here is a multi-line approach that uses your existing function definition (named rand , here):

var dd = rand(1,5) + rand(0,5);
var result;
if (dd > 5)
    result = dd - 5;
else result = 6 - dd;

One basic result is that if U is a random variable with uniform distribution and F is the cumulative distribution you want to sample from, then Y = G(X) where G is the inverse of F has F as its cumulative distribution. This might not necessarily be the most efficient way of doing and generating random numbers from all sort of distributions is a research subfield in and of itself. But for a simple transformation it might just do the trick. Like in your case, F(x) could be 4*(x-.5)^3+.5, it seems to satisfy all constraints and is easy to invert and use as a transformation of the basic random number generator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM