2010-05-01 6 views
30

Voglio generare numeri casuali con un intervallo (da n a m, ad esempio da 100 a 150), ma invece di casuale, voglio che i risultati siano basati sulla distribuzione normale.Numero casuale in un intervallo basato su una distribuzione normale

Con questo voglio dire che, in generale, voglio i numeri "raggruppati" intorno 125.

ho trovato questo pacchetto di numeri casuali che sembra avere un sacco di cose che mi servono: http://codeproject.com/KB/recipes/Random.aspx

E ' supporta una varietà di generatori casuali (include mersiene twister) e può applicare il generatore a una distribuzione.

Ma sono confuso, se uso un normale generatore di distribuzione i numeri casuali vanno da circa -6 a +8 (apparentemente l'intervallo vero è float.min a float.max).

Come si effettua una scala in base alla portata richiesta?

risposta

24

Una distribuzione normale standard ha media 0 e deviazione standard di 1; se si desidera effettuare una distribuzione con media m e deviazione s, moltiplicare semplicemente per s e quindi aggiungere m. Poiché la distribuzione normale è teoricamente infinita, non puoi avere un limite rigido nel tuo intervallo, ad es. (Da 100 a 150) senza rifiutare esplicitamente i numeri che non rientrano in essa, ma con una scelta appropriata di deviazione si può essere certi che (ad es.) Il 99% dei tuoi numeri sarà compreso nell'intervallo.

Circa il 99,7% di una popolazione è all'interno di +/- 3 deviazioni standard, quindi se si sceglie il vostro per essere circa (25/3), dovrebbe funzionare bene.

Così si desidera qualcosa di simile: (normal * 8.333) + 125

+0

Grazie ... questo ha molto senso :) – ConfusedAgain

+0

Prego. :) – tzaman

2

Questo potrebbe essere troppo semplicistico per le vostre esigenze, ma un rapido & modo economico per ottenere un numero casuale con una distribuzione che è ponderata verso il centro è semplicemente aggiungere 2 (o più) numeri casuali.

Pensa a quando tiri due dadi a 6 facce e aggiungili. La somma è più spesso 7, quindi 6 e 8, quindi 5 e 9, ecc. E solo raramente 2 o 12.

+0

Teorema del limite centrale significa che l'aggiunta di uniformi sarà approssimativa a una distribuzione normale, ma è un hacker e difficile da tenere traccia della varianza. – tzaman

+1

Richiede anche l'assunzione di un numero arbitrariamente elevato di campioni per una data approssimazione a una distribuzione normale. –

4

La risposta di tzaman è corretta, ma quando si utilizza la libreria collegata esiste un modo più semplice rispetto all'esecuzione della calcolo te stesso: l'oggetto NormalDistribution ha proprietà scrivibili Mu (che significa la media) e Sigma (deviazione standard). Quindi, passando dai numeri di tzaman, imposta Mu su 125 e Sigma su 8.333.

+0

Naturalmente, impostare direttamente quelli sarebbe più conveniente. :) +1 – tzaman

14

Per motivi di interesse, è abbastanza semplice per generare numeri casuali normalmente distribuite da un RNG uniforme (anche se deve essere fatto in coppia):

Random rng = new Random(); 
double r = Math.Sqrt(-2 * Math.Log(rng.NextDouble())); 
double θ = 2 * Math.Pi * rng.NextDouble(); 
double x = r * Math.Cos(θ); 
double y = r * Math.Sin(θ); 

x e y ora contengono due indipendenti, normalmente distribuito numeri casuali con media 0 e varianza 1. È possibile ridimensionarli e convertirli secondo necessità per ottenere l'intervallo desiderato (come spiega Interjay).


Spiegazione:

Questo metodo viene chiamato il Box–Muller transform.Utilizza la proprietà dell'unità gaussiana bidimensionale che il valore di densità stesso, p = exp(-r^2/2), è uniformemente distribuito tra 0 e 1 (costante di normalizzazione rimossa per semplicità).

Poiché è possibile generare facilmente tale valore utilizzando un RNG uniforme, si finisce con un contorno circolare di raggio r = sqrt(-2 * log(p)). È quindi possibile generare una seconda variabile casuale uniforme tra 0 e 2*pi per fornire un angolo θ che definisce un punto univoco sul contorno circolare. Infine, è possibile generare due variabili casuali normali i.i.d. trasformandole dalle coordinate polari (r, θ) in coordinate cartesiane (x, y).

Questa proprietà - quella p è distribuita uniformemente - non è valida per altre dimensionalità, motivo per cui è necessario generare esattamente due variabili normali alla volta.

+0

Interessante. Questo metodo ha un nome? Mi piacerebbe leggere di più su questo. Questa è un'approssimazione, giusto? –

+1

@Drew: Si chiama trasformazione Box-Muller: http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform –

+1

Grazie. Ho notato qui (http://stackoverflow.com/questions/2325472/generate-random-numbers-following-a-normal-distribution-in-cc/2325531#2325531) il suggerimento che si può tenere su 'u2' e utilizzare come 'u1' per la seguente chiamata, come ottimizzazione. Non si parla di questo sull'articolo di Wikipedia. Puoi commentare se questo mantiene la casualità? –

-1

Ecco un altro algoritmo che non ha bisogno di calcolare Sin/Cos, né ha bisogno di conoscere Pi. Non chiedermi del background teorico. L'ho trovato da qualche parte una volta ed è quello che uso da allora. Sospetto che sia una sorta di normalizzazione della stessa trasformazione Box-Muller che @Will Vousden menziona. Produce anche risultati in coppia.

L'esempio è VBscript; abbastanza facile da convertire in qualsiasi altra lingua.

Sub calcRandomGauss (byref y1, byref y2) 
    Dim x1, x2, w 
    Do 
     x1 = 2.0 * Rnd() - 1.0 
     x2 = 2.0 * Rnd() - 1.0 
     w = x1 * x1 + x2 * x2 
    Loop While w >= 1.0 Or w = 0 'edited this line, thanks Richard 

    w = Sqr((-2.0 * Log(w))/w) 
    y1 = x1 * w 
    y2 = x2 * w 
End Sub 
+1

"Non chiedermi del contesto teorico, l'ho trovato da qualche parte una volta". Ecco come si diffonde la conoscenza scorretta. Questa è una cattiva implementazione del metodo polare Marsaglia. È necessario eseguire il ciclo mentre 'w> = 1.0 OR w == 0'. Altrimenti, rischi di prendere 'log (0)' e far saltare il programma. – Richard

+0

Direi al contrario. Essere onesti riguardo al non avere alcun riferimento era inteso a impedire che la conoscenza scorretta si propagasse. Grazie per il riferimento e la correzione. – mgr326639

0

Un diverso approccio a questo problema utilizza la distribuzione beta (che ha una gamma duro, a differenza della distribuzione normale) e coinvolge scegliendo i parametri appropriati in modo tale che la distribuzione ha media proposta e la deviazione standard (radice quadrata della varianza). Vedi this question.