[RESOLVIDO] Numeros random não repetidos

Estou fazendo um exercício que consiste no preenchimento de uma cartela de bingo. Uma matriz 4x4 que recebe valores aleatórios e gera a cartela.
Porém, usando

Random r = new Random()
r.Next(intervalo)

gera números repetidos.
Como fazer para não ter repetição?

  1. Gere um número aleatório

  2. Salve o número que você gerou numa variável temporária

  3. Gere um novo número

  4. Compare. Seu novo número é igual ao numero que está na variável temporária?

  5. SE SIM:
    Não faça nada e gere um outro número
    SE NÃO:
    Sua variável temporária recebe o valor do gerador
    Adicione o valor na matriz

Repita a lógica até a matriz estar cheia.

[]'s

Acho que o correto seria:

  1. Gere um número aleatório
  2. Salve o número que você gerou numa variável temporária
  3. Compare. Seu novo número é igual a algum número que está na MATRIZ?
  4. SE SIM:
    Não faça nada e gere um outro número
    SE NÃO:
    Sua variável temporária recebe o valor do gerador
    Adicione o valor da variável na matriz

Repita até completar a matriz

1 curtida

O nome do que você quer é “amostragem sem reposição”, em inglês “sampling without replacement”.

Um dos jeitos mais simples, e quando a distribuição é uniforme, é usar o Knuth Shuffle:
https://www.rosettacode.org/wiki/Knuth_shuffle

PS: O algoritmo dos colegas descrito acima, funciona, porém tem viés e não gera uma distribuição uniforme, ou seja, no caso em questão a chance de um numero X aparecer no final da cartela é menor do que dele aparecer no começo. Com o algoritmo que citei acima esse viés não existe.

PS2:
Testei aqui e parece que eu estava errado, o método proposto pelos colegas da resultados equivalentes:

Teria que fazer uma análise melhor pra ter certeza, mas parece legítimo, pelo menos para fins práticos.

Código em:
https://colab.research.google.com/drive/1qa7NK9fpKjlyYKBOLPn62Ausu81jHJZE

1 curtida

Legal você ter feito essa análise @Kronal

Depois do seu post eu fui procurar entender onde esse viés estava e vi que isso acontece quando você tenta fazer um shuffle de um array usando rand diretamente.
Referências aqui:
https://blog.codinghorror.com/the-danger-of-naivete/

Mas como o método proposto aqui nao dá chance para um valor “sorteado” ser manipulado novamente, achei que nao teria esse viés, e num exemplo que testei aqui, realmente ele nao demonstra ter isso.

Para quem quer implementar essa soluçao com shuffle, no java temos o Collections.shuffle que já utiliza o algoritmo que você postou. Nao sei se existe algo equivalente no .NET

1 curtida
  • Qual é o range de números? (ou qualquer números) !!!
  • Exemplifique a repetição?
  • Basicamente seria talvez um esforço maior se fizer assim, poderia trabalhar com uma estrutura de apoio e removendo elementos tendo um fluxo único.

Isso, correto!