Generatore lineare congruenziale

In matematica il generatore lineare congruenziale (LCG dall'inglese Linear Congruential Generator) è un algoritmo per la generazione di numeri pseudo-casuali vecchio e molto conosciuto. La teoria sulla quale poggia è semplice da capire e da implementare; inoltre ha il vantaggio di essere computazionalmente leggero.

La disposizione dei punti generati dal Generatore Lineare ran0

Il generatore è definito ricorsivamente:

dove è un valore della successione dei numeri pseudocasuali e

— il "modulo"
— il "moltiplicatore"
— l'"incremento" (nel caso speciale in cui si parla di generatore Park-Miller RNG o moltiplicativo)
— il "seme" o il "valore iniziale"

Il periodo di un LCG è al più m, e per alcune scelte di a può essere molto più piccolo. Il LCG ha un periodo pieno se e solo se:

  1. e sono coprimi
  2. è divisibile per tutti i fattori primi di ,
  3. è un multiplo di 4 se è un multiplo di 4.[1]

Nonostante gli LCG siano generalmente in grado di produrre numeri pseudocasuali decenti, la loro qualità è molto sensibile alla scelta dei coefficienti c, m ed a.

Storicamente, scelte sbagliate hanno portato a implementazioni inefficienti di LCG. Un esempio significativo è RANDU che è stato usato largamente nei primi anni '70 e ha portato a dei risultati che attualmente sono messi in dubbio a causa dell'uso di un LCG di scarsa qualità[2].

Se un generatore congruenziale lineare è inizializzato con un carattere e iterato, il risultato è un semplice cifrario classico chiamato cifrario affine; questo cifrario è facilmente forzabile con un'analisi frequentista standard.

Esempi

Generatori di base

Grafico del Generatore lineare definito a lato. Si nota come la funzione è periodica di periodo 4

Un esempio di generatore di base può essere dato da

Ossia:

La sequenza generata è:

Il periodo è uguale a quattro.

Esempi di utilizzo

Il generatore congruenziale lineare più efficiente ha m uguale a una potenza di 2, spesso m = 232 o m = 264 perché questo consente di calcolare l'operazione modulo semplicemente troncando i 32 o i 64 bit meno significativi. La seguente tabella lista i parametri degli LCG di uso comune, inclusa le funzioni rand() di alcuni compilatori.

Sourcemacoutput bits of seed in rand() / Random(L)
Numerical Recipes23216645251013904223
Borland C/C++232226954771bits 30..16 in rand(), 30..0 in lrand()
glibc (usato da GCC)[3]232110351524512345bits 30..0
ANSI C: Watcom, Digital Mars, CodeWarrior, IBM VisualAge C/C++232110351524512345bits 30..16
Borland Delphi, Virtual Pascal2321347758131bits 63..32 of (seed * L)
Microsoft Visual/Quick C/C++2322140132531011bits 30..16
Apple CarbonLib231 − 1168070see Park–Miller RNG
MMIX di Donald Knuth26463641362238467930051442695040888963407
VAX's MTH$RANDOM,[4] old versions of glibc232690691
Random class nelle API di Java2482521490391711bits 48...17

[senza fonte]

Come mostrato sopra, LCG non usa sempre tutti i bit che produce. L'implementazione Java produce 48 bit ad ogni iterazione ma sono ritornati come risultato solo i 32 bit più significativi. Questo poiché i bit più significativi hanno un periodo più lungo. Gli algoritmi che usano questa soluzione sono migliori.

Vantaggi e svantaggi

I generatori congruenziali lineari richiedono una memoria minima (tipicamente 32 o 64 bit) per memorizzare lo stato.

Iperpiani di un generatore congruenziale lineare in tre dimensioni

Gli LCG non dovrebbero essere usati in applicazioni dove è critico l'utilizzo dell'alta casualità.

Per esempio, non sono adatti per simulazioni Monte Carlo poiché hanno una correlazione tra di loro. Non devono essere usati in crittografia.

Inoltre questi algoritmi tendono ad avere alcuni difetti. Per esempio, se un LCG è usato per scegliere i punti in uno spazio n-dimensionale, i punti giacciono su iperpiani al massimo m1/n-dimensionali (teorema di Marsaglia). Questo è dovuto ad una correlazione tra valori successivi della successione.

Un altro problema è che negli LCG i bit meno significativi della sequenza generata hanno un periodo più corto di quello della sequenza se m è posto ad essere una potenza di 2. In generale, la n-esima cifra meno significativa nella base b della sequenza prodotta, dove per qualche intero k, si ripete con un periodo al più .

Nonostante ciò, gli LGC possono essere una buona scelta in alcuni contesti, come per esempio nei sistemi embedded, dove la memoria disponibile è spesso molto limitata; anche nel caso di un videogioco, prendere un piccolo numero dei bit più significativi potrebbe essere sufficiente. I bit meno significativi di un LCG dove m è una potenza di 2 non dovrebbero mai essere usati.

Confronto con altri metodi

Se è necessario avere numeri pseudocasuali di qualità e una certa memoria è disponibile (~ 2 kilobytes), allora l'algoritmo Mersenne Twister fornisce un periodo molto maggiore (2^19937-1)

Note

Voci correlate

Collegamenti esterni