2010-04-28 17 views
9

Hola estoy teniendo algunos problemas para generar números aleatorios con C# Ahora tengo esta función.Encuentro aleatorio no tan aleatorio

public Color getRandomColor() 
{ 
    Color1 = new Random().Next(new Random().Next(0, 100), new Random().Next(200, 255)); 
    Color2 = new Random().Next(new Random().Next(0, 100), new Random().Next(200, 255)); 
    Color3 = new Random().Next(new Random().Next(0, 100), new Random().Next(200, 255)); 
    Color color = Color.FromArgb(Color1, Color2, Color3); 
    Console.WriteLine("R: " + Color1 + " G: " + Color2 + " B: " + Color3 + " = " + color.Name); 
    return color; 
} 

Ahora usted puede notar que hay una gran cantidad de nueva aleatorio() existe, es porque quiero eliminar a la probabilidad de que podría ser un ejemplo mismo error.

Ahora ejecuto esta función 8 veces, un par de veces. Ahora aquí están las salidas.

R: 65 G: 65 B: 65 = ff414141 
R: 242 G: 242 B: 242 = fff2f2f2 
R: 205 G: 205 B: 205 = ffcdcdcd 
R: 40 G: 40 B: 40 = ff282828 
R: 249 G: 249 B: 249 = fff9f9f9 
R: 249 G: 249 B: 249 = fff9f9f9 
R: 94 G: 94 B: 94 = ff5e5e5e 
R: 186 G: 186 B: 186 = ffbababa 

R: 142 G: 142 B: 142 = ff8e8e8e 
R: 190 G: 190 B: 190 = ffbebebe 
R: 19 G: 19 B: 19 = ff131313 
R: 119 G: 119 B: 119 = ff777777 
R: 119 G: 119 B: 119 = ff777777 
R: 75 G: 75 B: 75 = ff4b4b4b 
R: 169 G: 169 B: 169 = ffa9a9a9 
R: 127 G: 127 B: 127 = ff7f7f7f 

R: 73 G: 73 B: 73 = ff494949 
R: 27 G: 27 B: 27 = ff1b1b1b 
R: 125 G: 125 B: 125 = ff7d7d7d 
R: 212 G: 212 B: 212 = ffd4d4d4 
R: 174 G: 174 B: 174 = ffaeaeae 
R: 0 G: 0 B: 0 = ff000000 
R: 0 G: 0 B: 0 = ff000000 
R: 220 G: 220 B: 220 = ffdcdcdc 

Como puede ver, esto no es tan aleatorio de nuevo, pero ¿por qué ocurre esto? y ¿cómo puedo contrarrestarlo?

+0

Tuve el mismo problema al generar colores aleatorios en un rango normalizado. Una manera rápida sin proporcionar una semilla es permutar un par de valores usando la misma secuencia aleatoria. Falta de precisión pero se puede usar para obtener una distribución aleatoria un poco más variada. P. ej. int x = rng.Next()^rng.Next(); int magnitud = x * x; valor flotante = x/(flotante) magnitud; –

+0

Al usar este método, puede generar una distribución de color ligeramente mejor de la siguiente manera. Color = color = nuevo Color ( (byte) (rand.Next (0, 255)^rand.Next (0, 255)), (byte) (rand.Next (0, 255)^rand.Siguiente (0, 255)), (byte) (rand.Next (0, 255)^rand.Next (0, 255)), (byte) (rand.Next (0, 255)^rand.Next (0 , 255))) –

Respuesta

28

Está creando un nuevo Random por cada valor que necesite.

Intente crear un objeto único Random y llame a la función .Next() varias veces.

public Color getRandomColor() 
{ 
    Random rand = new Random(); 

    Color1 = rand.Next(rand.Next(0, 100), rand.Next(200, 255)); 
    Color2 = rand.Next(rand.Next(0, 100), rand.Next(200, 255)); 
    Color3 = rand.Next(rand.Next(0, 100), rand.Next(200, 255)); 
    Color color = Color.FromArgb(Color1, Color2, Color3); 
    Console.WriteLine("R: " + Color1 + " G: " + Color2 + " B: " + Color3 + " = " + color.Name); 
    return color; 
} 

Tomado de MSDN documentation on Random object:

Por defecto, el constructor sin parámetros de la clase Random utiliza el reloj del sistema para generar su valor inicial, mientras que su constructor con parámetros puede tener un valor Int32 basado en el número de garrapatas en el tiempo actual. Sin embargo, debido a que el reloj tiene una resolución finita, usando el constructor sin parámetros para crear diferentes objetos aleatorios en rápida sucesión crea generadores de números aleatorios que producen secuencias idénticas de números aleatorios

+4

Sí, esta es la respuesta. Las instancias de Random creadas muy rápidamente una después de la otra tienden a dar el mismo valor. Supongo que esto es porque el reloj de la computadora los sembra, pero eso no es más que una conjetura salvaje. –

+1

Exactamente. Random tiene 2 constructores. El parámetro toma utiliza la hora actual como la semilla. También puede usar el que toma un número entero. Entonces usará el argumento que pase como semilla. – emzero

+0

Mi código se veía así en el principio, creamos muchas instancias para ver si ese ayudante. Pero ahora tenemos R: 164 G: 78 B: 145 = ffa44e91 R: 206 G: 20 B: 149 = ffce1495 R: 206 G: 20 B: 149 = ffce1495 R: 73 G: 60 B: 94 = ff493c5e R: 147 G: 94 B: 101 = ff935e65 R: 212 G: 123 B: 61 = ffd47b3d R: 98 G: 79 B: 70 = ff624f46 R: 85 G: 110 B: 79 = ff556e4f Es un poco más aleatorio, pero si ve el resultado 2 y 3 son los mismos. – Androme

1

aleatoria funciona mejor cuando se utiliza una instancia de la misma.

Prueba esto: Objetos

public Color getRandomColor() 
{ 
    var random = new Random(); 
    Color1 = random.Next(random.Next(0, 100), random.Next(200, 255)); 
    Color2 = random.Next(random.Next(0, 100), random.Next(200, 255)); 
    Color3 = random.Next(random.Next(0, 100), random.Next(200, 255)); 
    Color color = Color.FromArgb(Color1, Color2, Color3); 
    Console.WriteLine("R: " + Color1 + " G: " + Color2 + " B: " + Color3 + " = " + color.Name); 
    return color; 
} 
+0

¿Cómo se edita algo más que el uso de un solo elemento aleatorio? Ciertamente, no es "más aleatorio"? – Will

+1

Incluso devolverá el mismo color "aleatorio" cada vez que se llame a la función. – Miles

5

Usted está creando muchos aleatoria secuencial, lo que hace que se sembraron con la misma casi la misma marca de tiempo /. Generando así números aleatorios pero iguales entre ellos.

Intenta crear una única instancia de Aleatorio y usarla para todas tus necesidades de números aleatorios.

7

Cada new Random() es seeded with the current time.

Si crea varias instancias Random en rápida sucesión, y su máquina lo ejecuta lo suficientemente rápido como para que estén lo suficientemente cerca para obtener la misma semilla, ¡devolverán la misma secuencia de valores!

Utilice un solo Random, llamando al .Next() para obtener cada valor.

Ahora usted puede notar que hay una gran cantidad de nueva aleatoria() existe, es decir porque quiero eliminar a los probabilidad de que podría ser un mismo error ejemplo.

Esto es una falacia; una secuencia de números de un solo Random está distribuida uniformemente - se ha dedicado esfuerzo para hacerlo aleatorio.