16

having an issue generating random numbers in a loop. Can get around it by using Thread.Sleep but after a more elegant solution.

for ...
    Random r = new Random();
    string += r.Next(4);

Will end up with 11111... 222... etc.

Suggestions?

Sam
  • 4,219
  • 7
  • 52
  • 80

5 Answers5

59

Move the declaration of the random number generator out of the loop.

The random number generation starts from a seed value. If the same seed is used repeatedly, the same series of numbers is generated. One way to produce different sequences is to make the seed value time-dependent, thereby producing a different series with each new instance of Random. By default, the parameterless constructor of the Random class uses the system clock to generate its seed value, ...

Source

By having the declaration in the loop you are effectively calling the constructor with the same value over and over again - hence you are getting the same numbers out.

So your code should become:

Random r = new Random();
for ...
    string += r.Next(4);
ChrisF
  • 134,786
  • 31
  • 255
  • 325
9
Random r = new Random(); 
for ... 
    string += r.Next(4); 

new Random() will initialize the (pseudo-)random number generator with a seed based on the current date and time. Thus, two instances of Random created at the same date and time will yield the same sequence of numbers.

You created a new random number generator in each iteration and then took the first value of that sequence. Since the random number generators were the same, the first value of their sequences was the same. My solution will create one random number generator and then return the first, the second, etc... value of the sequence (which will be different).

Heinzi
  • 167,459
  • 57
  • 363
  • 519
6

I found a page in Chinese that said the same with the time: http://godleon.blogspot.hk/2007/12/c.html, it said if you type like this:

Random random = new Random(Guid.NewGuid().GetHashCode());

you MAY get a random number even in a loop! It solved my question as well!

Daniel Cheung
  • 4,779
  • 1
  • 30
  • 63
  • why make it slow, just `Guid.NewGuid().GetHashCode()` will be enough – nawfal Apr 06 '13 at 11:37
  • @nawfal I don't really understand what you are saying??!! Didn't I did that? – Daniel Cheung Apr 09 '13 at 11:19
  • I meant `Guid.NewGuid().GetHashCode()` will be faster than `new Random(Guid.NewGuid().GetHashCode())`. Both gives random integers – nawfal Apr 10 '13 at 10:04
  • The page in Chinese uses THIS particular method is to slow it down so it can generate more random numbers as Random(s) used in a loop do not have enough time to generate. – Daniel Cheung Apr 12 '13 at 10:10
  • 1
    Instead of using new Guids hashcodes you can use simple int incremention through each loop cycle, that will change the Random seed parameter in constructor. This approach will be faster. – Fragment Jan 22 '15 at 07:45
  • @fragment why don't you add your answer too so we can have more choices :) – Daniel Cheung Jan 22 '15 at 10:46
2

You should be using the same Random instance throughout instead of creating a new one each time.

As you have it:

for ...
    Random r = new Random();
    string += r.Next(4);

the seed value is the same for each (it defaults to the current timestamp) so the value returned is the same.

By reusing a single Random instance like so:

Random r = new Random()
for ...
    string += r.Next(4);

Each time you call r.Next(4) the values are updated (basically a different seed for each call).

chills42
  • 14,201
  • 3
  • 42
  • 77
2

Move the Random r = new Random(); outside the loop and just call next inside the loop.

Servy
  • 202,030
  • 26
  • 332
  • 449
Brian
  • 4,974
  • 2
  • 28
  • 30
  • 2
    I should have reloaded the page. LOL everyone had the same answer – Brian Jun 16 '10 at 13:52
  • the question is "INSIDE OF LOOP" – Mironline Jul 14 '14 at 08:38
  • @Mironline maybe you didn't read my entire answer, I also state to leave "next inside the loop". The accepted answer was exactly as I described so I'm assuming it fit the OP's request. – Brian Jul 14 '14 at 19:07