Generating More Random Numbers

I'm currently using the following code to generate a random number between 0 and 6:

Random random = new Random();
int rand = random.Next(6);

It seems to repeat some numbers quite frequently though. What I'm wanting to know is if there's a better way to generate random numbers that seems more... random?

[316 byte] By [redneon] at [2007-12-25]
# 1
Your results are unpredictable though right?
dagfari at 2007-9-3 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,XNA Game Studio Express...
# 2
Yeah, but I was just wondering if there was a way to make them more unpredictable =o)
redneon at 2007-9-3 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,XNA Game Studio Express...
# 3

You're not creating a new Random instance everytime are you? Each Random instance starts with the same seed, unless you pass one in to the constructor, so you will get the same sequence of random numbers each time. Usually you would create and keep a Random object and then just call Next() whenever you need a number. If the problem is that you don't want the same sequence of random numbers everytime then you need to pass a new seed when you create your Random object. You could use the current time or something to get a random seed.

Cheers,
Leaf.

Leaf. at 2007-9-3 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,XNA Game Studio Express...
# 4
I'm creating an instance of Random every time I want a random number. I'll change this so I'm just using Next() and I'll create the instance with a seed of the current time too.
redneon at 2007-9-3 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,XNA Game Studio Express...
# 5
The Random.Next methods maxValue parameter is exclusive, so you are only generating random numbers from 0 to 5. If you want 0 to 6 you have to pass in 7.

Also, if you are only generating numbers from 0-5, then you can hardly be surprised that the same numbers repeat alot. You should even expect them to repeat the same number consecutively frequently (about 17% of the time).

If you just want to prove to yourself that the number distribution is suitably random, then generate a couple thousand numbers, keeping track of the results, and then compare how many times you got each number.

KrisNye at 2007-9-3 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,XNA Game Studio Express...
# 6
Leaf. wrote:

You're not creating a new Random instance everytime are you? Each Random instance starts with the same seed, unless you pass one in to the constructor, so you will get the same sequence of random numbers each time.

If you leave the parameter empty, "Random()", then the class will automatically use the timer as the seed.

dagfari at 2007-9-3 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,XNA Game Studio Express...
# 7

You're right, it will use a timer based seed, thanks for the correction. Unfortunately that timer doesn't appear to be very high frequency, which is why people who (mistakenly) recreate Random objects for each use sometimes see repeated sequences of numbers.

Some IronPython code that show's the problem:

>>> def RunRandom():
... for i in range(10):
... r = System.Random()
... for i in range(6):
... print r.Next(6),
... print System.Environment.TickCount
...
...
>>> RunRandom()
2 2 5 2 0 5 26809625
1 1 0 4 2 0 26809640
1 1 0 4 2 0 26809640
1 1 0 4 2 0 26809640
1 1 0 4 2 0 26809640
1 1 0 4 2 0 26809640
1 1 0 4 2 0 26809640
1 1 0 4 2 0 26809640
1 1 0 4 2 0 26809640
1 1 0 4 2 0 26809640

Cheers,
Leaf.

Leaf. at 2007-9-3 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,XNA Game Studio Express...
# 8
As shown by Leaf. s example, random() is not truly random, it is mearly a mathematical function which will return to you a sequency of numbers based on the given seed. If you keep recalling it with the same seed or even the time if done quickly enough you will see the same patterns arrise. You can easily sort this problem by making your random variable public to all of your classes so you can simply take it from there, or write some complicated manual workaround to check whether they are not identical, first would be easiest though.
PsychoDude at 2007-9-3 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,XNA Game Studio Express...
# 9
No computer random number function is truly random. However usually they are sufficient for most uses. The usual problem (besides the one we see here) is that the length of the random number sequence. If you want better read about Mersenne Twisters
TheZMan at 2007-9-3 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,XNA Game Studio Express...
# 10

I came across a similar issue with repetitive random seeds. I originally used this to generate new seed, but when I reused it when the code was running, the same seed was being used, and producing the same random figures.

Random rdm = new Random((int)unchecked(DateTime.Now.Ticks));

So I eventually replaced with this code, to generate different random seeds when running:

// Variable declaration.
int m_intRandomSeed;

public override void Start()
{

// Generate a seed value from the date time ticks.
Random rdmSeed = new Random((int)unchecked(DateTime.Now.Ticks));

// Store the next seed value.
m_intRandomSeed = rdmSeed.Next();

}

public void RandomNumber()
{
// Generate a set of random numbers from the seed.
Random rdm = new Random(this.m_intRandomSeed);

// Use the first random number for the seed of the next number.
this.m_intRandomSeed = rdm.Next();

// Generate the number between 0 and 6.
int int
RandomNo = rdm.Next(6);
}

So calling RandomNumber each time will also produce a different set of numbers.
Each time the routine is called the Seed number is always different.

Don't know if that will help you.

Pavcules at 2007-9-3 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,XNA Game Studio Express...
# 11
Thanks for all your help. I find the whole psuedo-random number generation thing quite interesting.

I've just had a quick thought though. After reading that the number of values I'm asking for might be a problem because it's too small, would I get better results if I generated a random number between 0 and say, 446578 or 126378 or 654723 (basically just any large number) and then modded it by 6?

redneon at 2007-9-3 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,XNA Game Studio Express...
# 12

No. In fact you would get a worse distribution since its likely that the core random number generator creates a base number which is not a multiple of 6 so there would be a slight bias.

e.g.

lets say the random number generator creates numbers 0-255 (8 bits) and you mod the result by 6.

you will get 43x0,1,2,3 and 42x4,5 which means your random numbers are not evenly distributed

Why does nobody trust that the .Net team knew what they are doing? Your problem was correctly diagnosed by leaf and you don't need to seed it with the time becuase the default constructor does this. I'm not 100% sure what Pavcules solution is trying to do but its just not required.

Just make a single Random (I ususally do it as a static on the class - no point is having one per instance most of the time) and call the methods provided.

class foo

{

private static Random random = new Random();

private void function()

{

int i = random.Next(6);

}

}

TheZMan at 2007-9-3 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,XNA Game Studio Express...
# 13
I did something like what the ZMan told.

A 100000x loop getting every value of i (random.Next(6)) and counting how many times each number came out. The diference between the max and min was below 5%, which I think is enough.

StudioPhoenix at 2007-9-3 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,XNA Game Studio Express...