Generador de números aleatorios en C # – valores únicos

Estoy ocupado en C # con la encoding de una matriz. Puedo llenarlo con generadores aleatorios, pero ahora me pregunto cómo hago esto, pero para poder verificar si el valor ya está en la matriz y, si es así, generar un nuevo valor

Información extra:
Valor máximo: 100
Cantidad de elementos: 100

IMPORTANTE TRABAJO PLZ MÁS ALLÁ DE MI IDEA

mi idea

public void FillArray(int[] A, int Range) { for (int I = 0; I < A.Length; I++) { A[I] = ValidNumber(T, I, Range); } } /* Fill Array */ 

Implementación del tipo de selección

 public void SelectionSort(int[] A) { int K, X; for (int I = 0; I < A.Length - 1; I++) { K = I; X = A[K]; for (int J = I + 1; J < A.Length; J++) { if (A[J] < X) { K = J; X = A[K]; } } A[K] = A[I]; A[I] = X; } } /* Selection sort */ 

Estas son solo algunas ideas, ahora quiero saber cómo puedo solucionarlo para poder mirar con selección, si hay allread allí (fillarray) que es lo mismo, si es así, reemplázalo con un nuevo valor aleatorio. Y entonces quiero crear una matriz aleatoria con enteros: de 1 a 100 en orden aleatorio

¿Cómo hago esto, pero para que pueda verificar si el valor ya está en la matriz y, si es así, generar un nuevo valor

No haces eso nunca, porque esa es una muy mala idea .

Para ilustrar por qué es una idea terrible, considere otra versión del mismo problema: clasifique un millón de números en un orden aleatorio mediante el siguiente proceso:

  1. Elija un número de uno a un millón.
  2. Verifique si ya está en la lista.
  3. Si es así, regrese al paso 1
  4. De lo contrario, agregue el número a la lista.
  5. ¿La lista tiene un millón de artículos? Si es así, has terminado. Si no, regrese al paso 1.

Claramente esto funciona ¿Es una buena idea? Supongamos que ya casi terminaste. La lista tiene 999999 ítems en ella. El único artículo que falta es 857313. ¿Qué haces? Usted elige un número aleatorio, digamos, 12. Ahora verifica los 999999 elementos en la lista para ver si alguno de ellos es 12. 12 podría haber sido uno de los primeros números que eligió, por lo que podría ser rápido encontrarlo. O podría ser uno de los últimos, por lo que llevará mucho tiempo. En promedio, se necesitarán 500000 comprobaciones para ver si 12 están en la lista. Y lo es, ya que solo falta un número en la lista.

12 no funcionó. Regresa al principio. Elija otro número aleatorio, digamos, 53259. ¿Está eso en la lista? Otro medio millón de cheques.

Sigue haciéndolo hasta que generes 857313, lo que ocurre uno cada millón de bashs.

Entonces, en promedio, poner el último elemento en la lista toma 500000 x 1000000 = quinientos mil millones de comparaciones. Podría llevar más. Puede tomar varios billones de comparaciones. O tal vez tengas suerte y te lleve una. Pero en promedio, medio billón de comparaciones.

Esta es una manera terrible de producir un orden aleatorio de una lista.

Hay dos buenas maneras de hacer un orden aleatorio de una lista.

(1) Cree un dispositivo que pueda ordenar una lista dada una función de pedido. Proporcione un orden estable basado en una semilla aleatoria.

Tenga en cuenta que no debe producir un orden aleatorio haciendo un método que arroje resultados aleatorios cuando se le pregunte “¿es A más grande que B?” Esa es una ordenación inestable; muchos algoritmos de clasificación se basan en un ordenamiento de clasificación estable y entrarán en bucles infinitos o tendrán otro comportamiento incorrecto cuando se les dé un orden de clasificación inestable.

Este algoritmo es O (n lg n) y tiene la agradable propiedad de que es muy fácil escribir partes estándar, como indican otras respuestas. También es extremadamente rápido para listas pequeñas en implementaciones típicas.

(2) Elija un ítem por índice de una lista de fonts al azar, eliminándolo de la lista fuente a medida que avanza, y colocándolo en la lista de destinos.

El último se conoce como Knuth Shuffle o Fischer-Yates Shuffle, y es un algoritmo muy rápido. Puede hacerlo “en su lugar”, mutando una matriz existente en orden aleatorio o creando una nueva lista. También tiene la buena propiedad de que puedes “pagar por jugar”, barajando la “cima” de la lista cuando la necesites. Si tiene un millón de elementos para mezclar pero solo necesita los primeros cien, puede calcular el orden de los primeros cien y llamarlo bueno.

Lo siguiente generará una matriz con los números 1-100 en orden aleatorio.

  Random rnd = new Random(); var randomNumbers = Enumerable.Range(1, 100).OrderBy(i => rnd.Next()).ToArray(); 

De su descripción tomo que necesita una matriz de 100 números enteros con valores de 1 a 100 y sin números duplicados. Si los números son enteros, no necesita generar números aleatorios, ya que todos los números posibles están en la matriz. Por lo tanto, solo el orden o los números se pueden aleatorizar.

Usando el enfoque de Linq y Jesper Palm, con la siguiente statement de Thomas Levesque te brindará la matriz que necesitas.

 Random rnd = new Random(); var randomNumbers = Enumerable.Range(1, 100) .Select(x => new { val = x, order = rnd.Next() }) .OrderBy(i => i.order) .Select(x => x.val) .ToArray(); 

El método es incluso bastante rápido, definitivamente más eficiente que cualquier operación de comparación.

Para explicar lo anterior al cartel original, vea el comentario a continuación:

  • Enumerable.Range(1, 100) crea un rango de enteros que comienza en 1 y termina en 100.
  • .Select(x => new { val = x, order = rnd.Next() }) crea un nuevo objeto temporal que contiene el valor y la posición del pedido, que está determinado por un número aleatorio.
  • .OrderBy(i => i.order) ordena los objetos temporales por su posición de orden.
  • .Select(x => x.val) selecciona el valor del objeto temporal, convirtiendo así de nuevo a int.
  • .ToArray() vuelve todo a una matriz de nuevo.

La syntax utilizada es LINQ, que está disponible en .NET 3.5. Con las versiones anteriores tendrías que implementarlo tú mismo, que es mucho más complicado y bastante más largo.

Siguiendo el comentario de Eric: Si se necesita barajar, puede hacer el código de la siguiente manera

 var list = myInputList; var result = list.Select(x => new { val = x, order = rnd.Next() }) .OrderBy(i => i.order) .Select(x => x.val) .ToArray(); 

Aquí hay una implementación ingenua:

 int[] values = new int[100]; Random random = new Random(); for(int i = 0; i < values.Length; i++) { int v; do { v = random.Next(100) + 1; } while (Array.IndexOf(values, v) != -1) values[i] = v; } 

Pero sería bastante ineficiente, especialmente cerca del final de la matriz ...

Una solución mejor sería considerar que, dado que desea 100 valores distintos de 1 a 100 en orden aleatorio, su matriz eventualmente contendrá todos los valores posibles de 1 a 100. Por lo tanto, solo necesita generar una secuencia de estos valores, y "mezclarlo":

 int[] values = Enumerable.Range(1, 100).ToArray(); Random random = new Random(); for(int i = values.Length - 1; i > 0; i--) { int j = random.Next(i + 1); int tmp = values[i]; values[i] = values[j]; values[j] = tmp; } 

EDIT: un mejor enfoque, que debería funcionar para casos menos específicos:

 T[] RandomCombinationWithNoRepeat(IEnumerable itemsToPickFrom, int numberOfItemsToPick) { // Copy original items to pick from, because we need to modify it List itemsCopy = new List(itemsToPickFrom); T[] array = new T[numberOfItemsToPick]; Random random = new Random(); for(int i = 0; i < numberOfItemsToPick; i++) { // Pick item and remove it from list int index = random.Next(itemsCopy.Count); array[i] = itemsCopy[index]; itemsCopy.RemoveAt(index); } return array; } 

En tu caso, lo usarías así:

 int[] result = RandomCombinationWithNoRepeat(Enumerable.Range(1, 100), 100); 

por lo que he entendido. Necesitas una colección de números enteros con números aleatorios. Asumo que usar int array o List of int no importa. Aquí hay un enfoque completo simple que usted ha descrito.
using System; using System.Collections.Generic; using System.Text;

espacio de nombres FillRandom {clase Progtwig {static void Main (string [] args) {int minValue = 1; int maxValue = 100; // crea una lista de int con capacidad establecida como 100 List array = new List (100);

  FillArray(array, minValue, maxValue, array.Capacity); //print out all values in the array foreach (int i in array) { Console.WriteLine(i); } } private static void FillArray(List array, int minValue, int maxValue, int capacity) { int count = 0; while (array.Count != capacity - 1) { Random rnd = new Random(); int value = rnd.Next(minValue, maxValue); if (!array.Contains(value)) { array.Add(value); } count++; } //print out the number of times the looping occurs Console.WriteLine("count: "+count); } } 

}

Puede crear un proyecto de consola y probarlo.

Intereting Posts