tags:

views:

345

answers:

5

Hi, I have been doing some testing on the Random class and I have used the following code:

while (x++ <= 5000000)
       {
           y = rnd.Next(1, 5000000);
           if (!data.Contains(y))
               data.Add(y);
           else
           {
               Console.WriteLine("Cycle {2}: Repetation found for number {0} after {1} iteration", y, x, i);
               break;
           }
       }

I kept changing the rnd max limit (i.e. 5000000) and I changed the number of iterations and I got the following result:

1) if y = rnd.Next(1, 5000) : The average is between 80 to 110 iterations
2) if y = rnd.Next(1, 5000000) : The average is between 2000 to 4000 iterations
3) if y = rnd.Next(1, int.MaxValue) : The average is between 40,000 to 80,000 iterations.

Why am I getting these averages, i.e. out of 10 times I checked for each value, 80% of the time I get within this average range. I dont think we can call it near to being Random.

What can I do to get a fairly random number.

+2  A: 

Per the documentation at http://msdn.microsoft.com/en-us/library/system.random.aspx

To generate a cryptographically secure random number suitable for creating a random password, for example, use a class derived from System.Security.Cryptography..::.RandomNumberGenerator such as System.Security.Cryptography..::.RNGCryptoServiceProvider.

David Stratton
+19  A: 

You are not testing for cycles. You are testing for how long it takes to get a random number you've had before. That's completely different. Your figures are spot on for testing how long it takes to get a random number you had before. Look in wikipedia under "the birthday paradox" for a chart of the probability of getting a collision after a certain number of iterations.

Coincidentally, last week I wrote a blog article about this exact subject. It'll go live on March 22nd; see my blog then for details.

If what you want to test for is the cycle length of a pseudo-random number generator then you need to look for not a number you've had before, but rather, a lengthy exact sequence of numbers that you've had before. There are a number of interesting ways to do that, but it's probably easier for me to just tell you: the cycle length of Random is a few billion, so you are unlikely to be able to write a program that discovers that fact. You'd have to store a lot of numbers.

However, cycle length is not the only measure of quality of a pseudo-random number generator. Remember, PRNGs are not random, they are predictable, and therefore you have to think very carefully about what your metric for "randomness" is.

Give us more details: why do you care how "random" Random is? What application are you using it for that you care? What aspects of randomness are important to you?

Eric Lippert
+1 @Eric: Are you filling upp your blog before release? That's funny.
Zano
@Zano: Yes, I write a whole pile of articles at once and then set them up to go live twice a week. I'm about two months ahead at any given time. Raymond Chen publishes like five or ten times a week and has several *years* worth in his queue; I don't know how he does it!
Eric Lippert
Hehe that's funny. But don't the articles get outdated, if you do it years ahead of time? For instance a newer version of .NET or C# would behave different, etc.
Joan Venge
+3  A: 

A computer can't generate a real random number. if You need a real random number (David gave you the best option from dot net framework) you need an external random source.

Dani
I like how random.org use the noises in atmospheric disturbance.
Pierre-Alain Vigeant
+4  A: 

You are judging randomness by repeat pairs, which isn't the best test for randomness. The repeats you see are akin to the birthday paradox: http://en.wikipedia.org/wiki/Birthday_problem, where a repeat event can occur with a small sample size if you are not looking for a specific event.

adharris
+10  A: 

You are assuming that the randomness is better if numbers are not repeated. That is not true.

Real randomness doesn't have a memory. When you pick the next number, the chance to get the same number again is just as high as any other number in the range.

If you roll a dice and get a six, then roll the dice again, there is no less chance to get a six again. If you happen to get two sixes in a row, that doesn't mean that the dice is broken.

The randomness in the Random class it of course not perfect, but that is not what your test reveals. It simply shows a penomenon that you get with every ranom number generator, even if actually creates real random numbers and not just pseudo-random numbers.

Guffa
+1 for the broken dice
jk
+1 very well explained
Bhaskar