Como semear uma class aleatória para evitar a obtenção de valores randoms duplicados

Eu tenho o seguinte código dentro de um método estático em uma class estática:

Random r = new Random(); int randomNumber = r.Next(1,100); 

Eu tenho isso dentro de um loop e continuo recebendo o mesmo randomNumber !

Alguma sugestão aqui?

Você não deve criar uma nova instância Random em um loop. Tente algo como:

 var rnd = new Random(); for(int i = 0; i < 100; ++i) Console.WriteLine(rnd.Next(1, 100)); 

A seqüência de números randoms gerados por uma única instância Random deve ser uniformemente distribuída. Ao criar uma nova instância Random para cada número random em sucessões rápidas, é provável que você as distribua com valores idênticos e faça com que gerem números randoms idênticos. Naturalmente, neste caso, a sequência gerada estará longe de ser uma distribuição uniforme.

Por uma questão de completude, se você realmente precisa reenviar um Random , você criará uma nova instância de Random com o novo seed:

 rnd = new Random(newSeed); 

Uma boa geração de sementes para mim é:

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

É muito random. A semente é sempre diferente porque a semente também é gerada aleatoriamente.

Caso você não possa, por algum motivo, usar o mesmo Random várias vezes, tente inicializá-lo com algo que muda o tempo todo, como o próprio tempo.

 new Random(new System.DateTime().Millisecond).Next(); 

Lembre-se que esta é uma prática ruim.

EDIT: O construtor padrão já leva sua semente do relógio e provavelmente melhor do que nós. Citando do MSDN:

Random (): Inicializa uma nova instância da class Random, usando um valor inicial padrão dependente do tempo.

O código abaixo é provavelmente sua melhor opção:

 new Random().Next(); 

Pouco tarde, mas a implementação usada pelo System.Random é Environment.TickCount :

 public Random() : this(Environment.TickCount) { } 

Isso evita ter que converter DateTime.UtcNow.Ticks de um longo, o que é arriscado de qualquer maneira, pois não representa pulsos desde o início do sistema, mas “o número de intervalos de 100 nanossegundos que se passaram desde a meia-noite, janeiro 1, 0001 (0:00:00 UTC em 1 de janeiro de 0001, no calendar gregoriano) “.

Estava procurando uma semente inteira boa para StringFactory.GenerateRandomString do StringFactory.GenerateRandomString

 public static Random rand = new Random(); // this happens once, and will be great at preventing duplicates 

Observe que isso não deve ser usado para propósitos criptocharts.

isso funciona para mim:

 private int GetaRandom() { Thread.Sleep(1); return new Random(DateTime.Now.Millisecond).Next(); } 

Uma boa boot de semente pode ser feita assim

 Random rnd = new Random((int)DateTime.Now.Ticks); 

Os carrapatos serão únicos e o casting em um int com provavelmente um valor solto será OK.

Eu uso isso para a maioria das situações, mantenha a semente se houver necessidade de repetir a sequência

  var seed = (int) DateTime.Now.Ticks; var random = new Random(seed); 

ou

  var random = new Random((int)DateTime.Now.Ticks);