Elija números aleatorios únicos

Intento aleatorizar un número en VB.NET 3 veces. Y cada vez que aleatorizo ​​un número, debería ser diferente de los otros dos.

Por ejemplo, tengo 3 enteros. Int1, Int2 e Int3. Voy a aleatorizar Int1 entre 1-10, y luego voy a aleatorizar Int2 entre 1-10 sin embargo, el valor no debe ser igual al valor que asigné al azar en Int1 y lo mismo ocurre con Int3 no debe ser igual a Int1 y Int2.

He descubierto cómo aleatorizar un número, este es el código que estoy usando:

Dim RndNumber As Random Dim num,num2 As Integer RndNumber = New Random num = RndNumber.Next(1, 11) num2 = RndNumber.Next(1, 11) 

Ahora estoy atascado en cómo hago num2 aleatorizar un número entre 1-10 que no es igual a num.

Agradezco cualquier ayuda, gracias.

En todos los ejemplos, RNG es un generador de números aleatorios creado a partir de la clase NET Random :

 Private RNG = New Random() 

Linq

Si solo necesita dos o tres, puede repetir hasta que la selección actual no esté en el conjunto de resultados. Pero esto es aún más simple usando algunos métodos de extensión:

 Dim nums = Enumerable.Range(1, 10). OrderBy(Function(r) RNG.Next). Take(3). ToArray() 

Esto comienza con todos los números entre 1 y 10, los pone en orden aleatorio, toma los primeros 3 y los almacena en la matriz nums . Usé la forma multilínea, rompiendo después de . s para ilustrar los pasos.

Simplemente cambie el rango, tamaño / conteo y elemento Take() según sea necesario. Por ejemplo, para algo así como una lotería con 5 números únicos 1-69 (forma condensada):

 Dim winners = Enumerable.Range(1, 69).OrderBy(Function(r) RNG.Next()).Take(5).ToArray() Dim powerball = Enumerable.Range(1, 26).OrderBy(Function(r) RNG.Next()).Take(1).First 

Como el Powerball puede ser una repetición de los primeros números, proviene de su propio grupo. Como solo queremos uno, no necesitamos una matriz, solo la First() .

Manual

Es bueno saber la lógica de estas cosas, así que esto muestra una versión manual. Esto lo hace de manera diferente, eligiendo y comprobando valores aleatorios:

 ' picked value storage Dim picks As New List(Of Int32) Dim pick As Int32 ' current candidate Do pick = RNG.Next(1, 11) If picks.Contains(pick) = False Then picks.Add(pick) End If Loop Until picks.Count = 3 

En lugar de perder vars, esto usa una lista para contener los picos. Esto hace que sea fácil ver si la selección actual ya ha sido seleccionada. Para más que unos pocos valores, utilice un HashSet(Of Int32) lugar de una lista para el rendimiento.

Pares aleatorios

Para crear conjuntos aleatorios de números con 2 de cada uno, como por ejemplo para un juego coincidente, simplemente duplique el grupo base de valores y luego póngalos en orden aleatorio:

 ' create pool of 2 values each for 1-13 Dim nums = Enumerable.Range(1, 13).ToArray() ' concat the set to make 2 of each value, randomize Dim pool = nums.Concat(nums).OrderBy(Function(r) RNG.Next).ToArray() 

Para un método manual, debe verificar el recuento de cada valor en el ciclo.

Selecciones de “agotamiento”

Una variación más es cuando necesita un conjunto de randoms usados ​​periódicamente, pero no sabe cuántos necesitará por adelantado. Ejemplos serían las bolas para un juego de BINGO o una baraja de cartas.

En lugar de un indexador global que apunta a la última ranura utilizada (o la siguiente ranura para usar), una Stack(Of T) (o una Queue ) “agotará” los valores cuando los necesite:

 ' create, randomize pool of 100 ints Dim nums = Enumerable.Range(1, 100).OrderBy(Function(r) RNG.Next).ToArray ' use array to create Stack Dim shoe As New Stack(Of Int32)(nums) ' same as: Dim shoe = New Stack(Of Int32)(Enumerable.Range(1, 100). OrderBy(Function(r) RNG.Next).ToArray()) 

Esto comienza básicamente igual con 100 enteros, aleatorizados y almacenados en una matriz, pero no hay Take(n) porque los queremos a todos. Luego, los valores se almacenan en una colección de stacks. Utilizándolo:

 Console.WriteLine(shoe.Count) For n As Int32 = 1 To 3 Console.WriteLine("Picked #{0}", shoe.Pop) Next Console.WriteLine(shoe.Count) 

Cuando Pop un valor, se elimina de la colección automáticamente. Si usa muchos valores del zapato, querrá verificar el recuento para asegurarse de que no esté vacío.

100
Elegido # 12
Elegido # 69
Elegido # 53
97

Después de dibujar 3 valores, la zapatilla solo tiene 97 valores restantes.

Notas aleatorias

En todos los casos, su generador Random debe ser un objeto de nivel de forma que cree una vez . Nunca los cree en un bucle o probablemente obtendrá el mismo valor una y otra vez.

El método de aleatorización OrderBy(Function(r) RNG.Next) suele ser lo suficientemente bueno para un uso casual, pero es ineficiente. Si va a aleatorizar grandes conjuntos y / o usarlos con frecuencia, debería considerar usar un orden aleatorio adecuado, como la mezcla de Fisher-Yates que se muestra aquí .