Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uniformity of random numbers taken modulo N

Tags:

c

random

uniform

One common way of choosing a random number in [0, n) is to take the result of rand() modulo n: rand() % n. However, even if the results returned by the available rand() implementation are fully uniform, shouldn't there be a problem with the uniformity of the resulting [0, n) numbers when RAND_MAX + 1 does not divide evenly by n? E.g. suppose RAND_MAX is 2, and n is 2. Then out of 3 possible rand() outputs: 0, 1 and 2, we get 0, 1 and 0 respectively when we use them modulo n. Therefore the output will not be uniform at all.

Is this a real problem in practice? What is a better way of choosing random numbers in [0, n) uniformly deriving from rand() output, preferably without any floating point arithmetic?

like image 846
dragonroot Avatar asked Oct 27 '12 21:10

dragonroot


People also ask

Does Rand mod n generate a number uniformly distributed?

Then out of 3 possible rand() outputs: 0, 1 and 2, we get 0, 1 and 0 respectively when we use them modulo n. Therefore the output will not be uniform at all.

What is uniformity of random numbers?

The Uniform Random Number block generates uniformly distributed random numbers over a specifiable interval with a specifiable starting seed. The seed is reset each time a simulation starts. The generated sequence is repeatable and can be produced by any Uniform Random Number block with the same seed and parameters.

How do you generate uniformly distributed random numbers?

Use rand to generate 1000 random numbers from the uniform distribution on the interval (0,1). rng('default') % For reproducibility u = rand(1000,1); The inversion method relies on the principle that continuous cumulative distribution functions (cdfs) range uniformly over the open interval (0,1).

What is modulus in random number generator?

Use the modulo (%) operator to generate random numbers within a specific range. The example below generates whole numbers within a range of 1 to 6. int main () { for (int x = 1; x <= 10; x++) { cout << 1 + (rand() % 6) << endl; } } /* Output: 6 6 5 5 6 5 1 1 5 3 */ but when i wish to use range between 2 to 9 .


2 Answers

You are correct, rand() % N is not precisely uniformly distributed. Precisely how much that matters depends on the range of numbers you want and the degree of randomness you want, but if you want enough randomness that you'd even care about it you don't want to use rand() anyway. Get a real random number generator.

That said, to get a real random distribution, mod to the next power of 2 and sample until you get one in the range you want (e.g. for 0-9, use while(n = rand()%0x10 > 10);).

like image 149
Kevin Avatar answered Sep 27 '22 20:09

Kevin


That depends on:

  • The value of RAND_MAX
  • Your value of N

Let us assume your RAND_MAX is 2^32. If N is rather small (let's say 2) then the bias is 1 / 2^31 -- or too small to notice.

But if N is quite a bit larger, say 2^20, then the bias is 1 / 2^12, or about 1 in 4096. A lot bigger, but still pretty small.

like image 43
slashingweapon Avatar answered Sep 27 '22 19:09

slashingweapon