Numeri Random
D.E.I.S. Università di Bologna
DEISNet
http://deisnet.deis.unibo.it/
Introduzione
• Può sembrare assurdo usare un computer per generare
numeri casuali:
– Il computer è una macchina deterministica - l’output è
perfettamente predicibile a priori.
• Tuttavia le sequenze di numeri casuali prodotte da
computer sono di uso comune.
• Nel seguito chiameremo
– Sequenze casuali (random)
• sequenze di numeri prodotte da fenomeni fisici intrinsecamente
aleatori (ad es.: tempo trascorso fra due impulsi successivi di un
contatore Geiger)
– Sequenze pseudo-casuali (pseudo-random)
• sequenze di numeri prodotte dal calcolatore utilizzabili “come se “
fossero sequenze casuali.
2
Sequenze pseudo-random
• Definizione operativa di sequenza pseudo-random
– “una sequenza di numeri si assimila ad una sequenza casuale
se il programma che la produce è diverso e, sotto ogni aspetto
misurabile, statisticamente incorrelato dal programma che usa il
suo output”
• In altre parole la sequenza pseudo-casuale deve “apparire” del tutto
casuale all’applicazione che la utilizza, per servire allo scopo
• Pertanto:
– Due generatori di sequenze pseudo-casuali devono produrre lo
stesso risultato (dal punto di vista statistico) se utilizzati come
ingresso dello stesso programma
• In caso contrario, almeno uno dei due non è un buon generatore
– Esiste una serie di test statistici per valutare la bontà di un
generatore
• Un generatore che non supera tali test potrebbe non essere un
buon generatore
3
Variabili Aleatorie Uniformi
• Variabile aleatoria (VA) uniforme
– I valori della v.a. sono equiprobabili e cadono in uno
specifico intervallo
• Nell’implementazione al calcolatore tipicamente da 0 a 1
• Nell’implementazione della generazione di
sequenze pseudo-random le VA uniformi sono
un punto di riferimento
– VA con altre distribuzioni di probabilità vengono quasi
sempre generate a partire da VA uniformi, mediante
opportune operazioni
• La VA uniforme è il mattoncino elementare per
ogni modello stocastico implementato
utilizzando sequenze pseudo-random
4
Numeri Random in C
L’ANSI C fornisce le seguenti funzioni per la generazione
di numeri casuali (V. Numerical Recipes in C):
#include <stdlib.h>
#define RAND_MAX...
void srand(unsigned seed);
int rand(void);
srand(seed): serve per inizializzare il generatore con un
arbitrario valore di seed: a valori uguali di
seed corrispondo identiche sequenze.
rand():
restituisce il successivo numero, compreso
fra 0 e RAND_MAX
5
Generatori lineari congruenziali
• I generatori di numeri casuali più semplici sono di tipo
lineare congruenziale
• Se Zi è il generico numero i-esimo della sequenza
pseudo-casuale allora:
Zi-1 = a · Zi + c (mod m)
• Dove:
– l’operatore mod indica il resto della divisione
– a si chiama moltiplicatore e c viene detto incremento.
– Z0 (primo valore della sequenza) si chiama seme (seed).
• Il generatore si dice moltiplicativo se c = 0
– Quindi vengono generati al più m numeri interi Zi distinti con 0 ≤
Zi ≤ m - 1.
• Per ottenere numeri casuali Ui uniformemente distribuiti
in [0,1) è sufficiente definire Ui = Zi /m
6
Generatori lineari congruenziali
Pro:
1. Estrema velocità di generazione
Contro:
1. Sequenza periodica di periodo al più pari a m.
• Occorre scegliere un valore di m elevato e valori di
a, c e Z0 tali da avere periodo massimo.
2. Ogni valore di Zi è completamente determinato
dai quattro parametri m, a, c e Z0.
3. Non c’è assenza di correlazione fra chiamate
successive del generatore.
7
Correlazione
• Se k numeri consecutivi della sequenza vengono
utilizzati come coordinate di punti in uno spazio kdimensionale (ciascuna coordinata fra 0 e 1)
– Se i numeri fossero assolutamente incorrelati i punti
tenderebbero a coprire tutto lo spazio
– In realtà i punti vanno a cadere in “piani” (k-1) - dimensionali, il
cui numero è al massimo m1/k.
Esempio:
m = 32768 ( cattiva scelta)
k=3
#piani = 327681/3 = 32
Occorre una scelta accurata di m, a e c al fine di
massimizzare k
8
Esempi: ran0
• Non è un ottimo generatore ma costituisce uno standard
minimo qualitativo per un generatore di numeri casuali.
• Generatore lineare congruenziale con:
a = 75 =16807
m = 231 - 1 = 2147483647
c =0
Difetti:
– Non si può usare seed = 0
– A causa dell’estrema semplicità della routine, numeri piccoli
tendono ad essere seguiti sempre da numeri grandi:
• Normalizzando i valori ad 1, mediamente c’è un valore < 10-6 ogni
106 chiamate. Questo però è sempre seguito da un valore ≤ 0.0168.
– Correlazione fra numeri successivi
• Si nota disponendo i numeri, presi a coppie, in un grafico
bidimensionale
9
Esempi: ran1
• Risolve il problema della correlazione fra
chiamate successive di ran0
– genera i numeri con ran0 e permuta l’uscita
È necessaria una fase di
inizializzazione del vettore iv,
con valori calcolati con ran0.
Ad ogni chiamata il valore nel
vettore iv, alla posizione iy è
scelto come uscita e come
successivo iy.
L’elemento scelto viene
sostituito da uno nuovo,
calcolato ancora con ran0.
10
Esempi: ran2
• Ran1 supera i test in cui ran0 fallisce.
– Inizia ad avere problemi quando il numero di chiamate è
abbastanza elevato, > 108 cioè circa m/20.
• Il rimedio consiste nel combinare due sequenze di
numeri casuali con diversi periodi m1 e m2
– Il periodo della sequenza risultante diventa il minimo comune
multiplo dei due periodi.
• L’idea base consiste nel sommare i valori ottenuti dai
due generatori.
– Questo accorgimento è implementato nella routine ran2, la quale
adotta anche una permutazione dell’uscita simile a ran1.
• Con i valori di m1 e m2 adottati, ran2 ha un periodo di
circa 2.3x1018 e costituisce un ottimo generatore di
numeri casuali.
11
Mersenne Twister (MT)
• Sviluppato nel 1997 da Makoto Matsumoto e Takuji
Nishimura
• Provvede alla generazione veloce di numeri casuali di
qualità molto elevata
• Principali caratteristiche:
– Periodo ben più lungo e migliore equidistribuzione rispetto a
qualsiasi generatore precedente:
• È stato dimostrato che il periodo è 219937 -1 e i numeri sono
distribuiti uniformemente in un iperspazio a 623 dimensioni.
• Questo significa che la correlazione fra valori successivi della
sequenza è praticamente trascurabile.
– Generazione veloce: la velocità di generazione di numeri
casuali è sostanzialmente uguale a quella di rand() presente
nella libreria standard dell’ANSI C.
– Uso efficiente della memoria: la versione in C del generatore è
costituita da 624 parole di codice.
12
Mersenne Twister (MT)
In dettaglio:
• Il generatore MT è stato progettato rispettando le condizioni pratiche
che un buon generatore di numeri random deve soddisfare. Non
esistono infatti metodi matematici rigorosi per dimostrare l’assenza
di difetti di un generatore.
Una della prove più forti per selezionare un buon generatore è
sicuramente il test spettrale. MT è in grado di superare un test di
questo tipo, ed in particolare il k-distribution test:
se si osserva un periodo dell’uscita del generatore con 32 bit di
accuratezza, le n-uple di numeri con n=623, si distribuiscono
uniformemente in uno spazio a 623 dimensioni. Analogamente, con
un’accuratezza a 16 bit, le n-uple di numeri con n=1246, si
distribuiscono uniformemente in uno spazio a 1246 dimensioni e
con un’accuratezza a 2 bit in 9968 dimensioni.
13
Esempi: altri
• Si ricordano altri tipi di generatori:
– Ran3: non utilizza il metodo lineare congruenziale ma
il metodo sottrattivo;
– generatori “Quick and Dirty”: molto semplici,
permettono di ottenere numeri casuali con poche
linee di codice e limitate risorse di elaborazione
14
Esempi
•
A partire da ran0 sono stati introdotti generatori via via più complicati, in
grado di superare test statistici più stringenti.
•
La maggiore complicazione di questi generatori causa un tempo di
esecuzione maggiore di ran0. Nella tabella seguente si riportano i tempi di
esecuzione relativi, ponendo come riferimento il generatore ran0.
•
Nella scelta di un generatore si deve tener presente il periodo:
la sequenza di numeri da generare deve essere molto minore del periodo
15
Considerazioni conclusive
• Le caratteristiche che deve avere un generatore di
sequenze pseudocasuali:
– Ripetibilità, affinché sia possibile ripetere gli stessi esperimenti
più volte
– Soddisfacimento dei test: servono per verificare che il
generatore sia quanto più simile ad un generatore di numeri
casuali ideale.
– Semplicità e rapidità: un simulatore che usa il generatore risulta
quindi efficiente.
– Periodicità lunga, in modo da poter effettuare simulazioni lunghe
senza riutilizzare più volte la stessa sequenza.
– Portabilità, cioè rendere l’implementazione del generatore
indipendente dalla piattaforma.
16
Test Statistici
• Per valutare la bontà di un generatore si
eseguono test statistici sulle sequenze ottenute.
• I tre metodi fondamentali sono:
– test di uniformità o del χ2 (chi quadro)
– test di Kolmogorov-Smirnov
17
Test di uniformità o del χ2
• Serve per misurare l'uniformità della distribuzione di una
sequenza.
– Si applica a variabili casuali discrete o discretizzate
• Dati k eventi possibili: E1, E2, … , Ek con probabilità p1,
p2, … , pk si fanno n esperimenti in cui si osservano y1
eventi di tipo E1, y2 eventi di tipo E2, … , yk eventi di tipo
Ek. Vale:
• La variabile:
ha una distribuzione detta χ2 con k-1 gradi di libertà.
Nota: il termine npi rappresenta la frequenza attesa di
istanze di Ei.
18
Test di uniformità o del χ2
• V è indipendente da pi se n è grande (si richiede
di solito che
).
• Per verificare l’uniformità di un generatore di
numeri random distribuiti uniformemente in [0,1]:
– Si creano k-sottointervalli di ampiezza 1/k.
– Si genera un gran numero di istanze della va
uniforme e si conta per ogni intervallo il numero yi di
istanze che sono cadute all’interno dell’intervallo.
Poiché il generatore è
uniforme si ha: pi = 1/k
1/k
1
1/k
1
19
Test di uniformità o del χ2
– Si calcola il valore di V. Se il generatore è buono, la variabile V
risulta avere la distribuzione χ2 con k-1 gradi di libertà.
df = # gradi di libertà = k - 1
– Il test è superato se, fissato un certo valore critico χ21-α , V non è
maggiore a tale valore.
– Tipicamente 1 - α = 0,95 ; il valore corrispondente χ21-α si trova
in forma tabulare.
20
Test di uniformità o del χ2
df
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1 - ! = 0.95
3.84
5.99
7.82
9.49
11.07
12.59
14.07
15.51
16.92
18.31
19.68
21.03
22.36
23.69
25.00
26.30
27.59
28.87
30.14
31.41
1 - ! = 0.99
6.64
9.21
11.35
13.28
15.09
16.81
18.48
20.09
21.67
23.21
24.73
26.22
27.69
29.14
30.58
32.00
33.41
34.81
36.19
37.57
1 - ! = 0.999
10.83
13.82
16.27
18.47
20.52
22.46
24.32
26.13
27.88
29.59
31.26
32.91
34.53
36.12
37.70
39.25
40.79
42.31
43.82
45.32
21
Test di Kolmogorov-Smirnov
• È un metodo che si applica a variabili casuali continue.
– Data una sequenza di n istanze xi della variabile casuale X , si
fissa un valore di x e si calcola il numero mx di istanze minori di
x all’interno della sequenza:
• Si costruisce quindi la funzione:
FN (x) = mx / n
che si confronta con F(x)
22
Test di Kolmogorov-Smirnov
•
D è la differenza massima, in
valore assoluto, tra la
distribuzione teorica F(x) e quella
osservata FN(x):
D = max | FN(x) - F(x) |
• Se x1, x2, ..., xN è un campione
casuale, FN(x) rappresenta il
numero (rapportato ad N) degli
elementi del campione xi, minori
od uguali ad x.
– Nella figura si vede che, da come
è stata definita, FN(x) è costante
tra xi e xi+1 e ogni gradino è pari
ad 1/N.
23
Test di Kolmogorov-Smirnov
• Analogamente al caso del test del chi-quadro,
D viene confrontato con certi valori critici Da (ad
esempio 0.01 o 0.05) per decidere se accettare
o meno l'ipotesi che i numeri ui siano equamente
distribuiti.
• A differenza del test del chi-quadrato, il test di
Kolmogorov e Smirnov offre il vantaggio di non
richiedere che i dati siano in qualche modo
raggruppati e, quindi, non dipende da come
vengono scelte le categorie nelle quali ripartire
la sequenza.
24
Distribuzioni non uniformi
• A partire da un algoritmo di generazione di
numeri uniformemente distribuiti è possibile
ricavare sequenze con distribuzioni diverse.
Gli approcci da seguire sono:
– Metodo della trasformazione inversa
– Metodo della reiezione
25
Metodo della trasformazione inversa
Si vuole generare una variabile aleatoria X con funzione
di densità di probabilità fX(x).
1. Si calcola la funzione di distribuzione di probabilità o
funzione cumulativa di probabilità:
Tale funzione è continua, monotona crescente ed è
sempre compresa tra 0 e 1 (per definizione FX(x) = P[X
≤ x])
2. Si pone y = FX(x) ∈ [0,1] dove y è un’istanza di una
variabile casuale Y con distribuzione uniforme in [0,1]
3. L’operazione x = F-1(y) fornisce un’istanza della
variabile X.
26
Metodo della trasformazione inversa
• Poiché Y è una variabile aleatoria uniformemente
distribuita in [0,1], si ha:
P{Y ≤ y} = y
cioè:
P{Y ≤ F(x)} = F(x)
Se esiste la F-1(), possiamo scrivere:
P{F-1(Y) ≤ F-1(F(x))} = P{F-1(Y) ≤ x} = F(x)
cioè F-1(Y), ha distribuzione F(x).
27
Metodo della trasformazione inversa
Questo metodo si giustifica intuitivamente in modo grafico come segue
Si scelgono due intervalli con la
medesima ampiezza Δx1 e Δx2
ai quali corrispondono gli intervalli
Δy1 e Δy2.
Generando uniformemente y in
[0,1] osserveremo molto più
frequentemente valori di y
nell’intervallo Δy1 che all’interno
dell’intervallo Δy2
Applicando il metodo dell’inversa
verranno generati più
frequentemente valori in Δx1 che
in Δx2.
28
Esempio
• Generazione di una variabile aleatoria con distribuzione
esponenziale
• Invertendo la F(x):
F(x)
1
F(x) = 1 – e –µx
y = 1 – e –µx
ln( 1 – y ) = –µx
x = – ln( 1 – y )/µ
x
• Quindi, generando y uniforme in [0,1] e calcolando x
come nella formula precedente, si ottiene un’istanza x di
una variabile aleatoria esponenziale a valore medio µ.
29
Metodo di reiezione
• È un metodo molto utile quando la funzione cumulativa
non è nota o non è invertibile analiticamente. Affinché
sia applicabile è necessario che la funzione densità di
probabilità f(x) abbia supporto finito:
f(x)
M
a
b
x
Nell’esempio il supporto è l’intervallo [a,b]; M è il valore
massimo assunto da f(x).
30
Metodo di reiezione - procedura
1. Si generano coppie di numeri casuali (x,y) con x distribuito
uniformemente in [a,b] e y in [0,M].
2. Interpretando (x,y) come un punto del piano, si osserva la sua
posizione rispetto la curva f(x):
f(x)
M
A
a
B
b
x
3. Se il punto cade al di sotto della curva f(x) viene considerata
l’ascissa, cioè x (caso A);
se il punto cade all’esterno della curva, si genera una nuova coppia
(caso B).
31
Metodo di reiezione
• I punti (x,y) vengono generati in modo uniforme pertanto
la probabilità di accettare il valore x è pari al rapporto fra
l’area sottesa da f(x) cioè 1 e l’area del rettangolo:
P = 1 / [ M (b - a) ]
• Il numero medio di punti generati nel piano per ottenere
un’istanza valida della variabile è:
Quindi il numero di istanze di variabile aleatoria uniforme
che devono essere generate è pari a 2M(b-a).
• L’efficienza di questo metodo risulta dipendente dalla
forma f(x) e in particolare della dimensione della
dimensione del rettangolo che la racchiude.
32
Distribuzione Gaussiana
• La densità di probabilità di una distribuzione
gaussiana non è invertibile analiticamente. Di
solito viene generata nei seguenti metodi:
– Si sommano 12 v.a. uniformi indipendenti tra -0,5 e
0,5. Per il teorema del limite centrale il risultato tende
alla distribuzione gaussiana. La media è nulla e la
varianza diventa 1. Da notare che il supporto della
v.a. risulta limitato tra -6 e +6
– Si approssima l’andamento della gaussiana con archi
di sinusoide
33