2010-04-28 1 views
9

Ciao sto avendo qualche problema a generare numeri casuali con C# Ora ho questa funzione.Incontro casuale non così casuale

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; 
} 

Ora si potrebbe notare che ci sono un sacco di new Random() c'è, è perché voglio estirpare la probabilità che potrebbe essere un errore stesso esempio.

Ora eseguo questa funzione 8 volte, un paio di volte. Ora ecco le uscite.

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 

Come potete vedere questo non è di nuovo in modo casuale, ma il motivo per cui dosare questo accade? e come posso contrastarlo?

+0

Ho avuto questo stesso problema generando colori casuali in un intervallo normalizzato. Un modo rapido senza fornire un seme è quello di permutare insieme un paio di valori usando lo stesso flusso casuale. Mancanza di precisione ma può essere utilizzato per ottenere una distribuzione casuale leggermente più varia. E.g. int x = rng.Next()^rng.Next(); int ampiezza = x * x; valore float = x/(float) grandezza; –

+0

Utilizzando questo metodo è possibile generare una distribuzione dei colori leggermente migliore come segue. Colore = colore = nuovo Colore ( (byte) (Rand.Next (0, 255)^Rand.Next (0, 255)), (byte) (Rand.Next (0, 255)^Rand.Next (0, 255)), (byte) (Rand.Next (0, 255)^Rand.Next (0, 255)), (byte) (Rand.Next (0, 255)^Rand.Next (0 , 255))) –

risposta

28

Si sta creando un nuovo Random per ogni singolo valore necessario.

Provare a creare un oggetto unico Random e chiamare la funzione .Next() più volte.

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; 
} 

Tratto da MSDN documentation on Random object:

Per impostazione predefinita, il costruttore senza parametri della classe Random utilizza l'orologio di sistema per generare il valore del seme, mentre il suo costruttore con parametri può assumere un valore Int32 in base al numero di zecche nel tempo corrente. Tuttavia, perché l'orologio ha risoluzione finita, utilizzando il costruttore senza parametri per creare diversi oggetti casuali in stretta successione crea generatori di numeri casuali che producono sequenze identiche di numeri casuali

+4

Sì, questa è la risposta. Le istanze di Random create molto rapidamente una dopo l'altra hanno la tendenza a dare lo stesso valore. Presumo che ciò sia dovuto al fatto che vengono seminati dall'orologio del computer, ma non è altro che congetture selvagge. –

+1

Esattamente. Casuale ha 2 costruttori. Il parametro senza parametri utilizza l'ora corrente come seme. Puoi anche usare quello che prende un numero intero. Quindi userà l'argomento che passi come seme. – emzero

+0

Il mio codice sembrava così all'inizio, abbiamo creato le molte istanze per vedere se quell'assistente. Ma ora otteniamo 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 È un po 'più casuale, ma se vedi i risultati 2 e 3 sono uguali. – Androme

1

casuale funziona meglio quando si utilizza un'istanza di esso.

Prova questa:

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

In che modo la modifica è nient'altro che lenta rispetto all'utilizzo di un singolo casuale? Non è certamente "più casuale"? – Will

+1

Sarà anche utile restituire lo stesso colore "casuale" ogni volta che viene chiamata la funzione. – Miles

5

Si sta creando molti a caso gli oggetti in modo sequenziale, che li induce a essere seminati con lo stesso/quasi la stessa data e ora. Così generando numeri casuali ma uguali tra loro.

Provare a creare una singola istanza di Casuale e utilizzarla per tutte le esigenze del numero Casuale.

7

Ogni new Random() è seeded with the current time.

Se crei più istanze Random in rapida successione e la tua macchina la esegue abbastanza velocemente da essere abbastanza vicine per ottenere lo stesso seme, restituiranno la stessa sequenza di valori!

Utilizzare un singolo Random, chiamando .Next() per ottenere ogni valore.

Ora si potrebbe notare che ci sono un sacco di new Random() c'è, cioè perché voglio estirpare la probabilità che potrebbe essere un stesso errore esempio.

Questo è un errore; un flusso di numeri da un singolo Random è equamente distribuito - lo sforzo è stato fatto per renderlo casuale.