Tipici generatori di numeri pseudo-casuali calcolano nuovi numeri in base a quelli precedenti, quindi in teoria sono completamente deterministici. L'unica casualità è garantita fornendo un buon seed (inizializzazione dell'algoritmo di generazione di numeri casuali). Finché i numeri casuali non sono molto critici per la sicurezza (ciò richiederebbe numeri "reali" casuali), un generatore di numeri casuali ricorsivo spesso soddisfa i bisogni.
La generazione ricorsiva può essere espressa senza alcuna funzione "esterna", una volta fornito un seme. Ci sono un paio di algoritmi per risolvere questo problema. Un buon esempio è lo Linear Congruential Generator.
Un'implementazione pseudo-codice potrebbe essere simile alla seguente:
long a = 25214903917; // These Values for a and c are the actual values found
long c = 11; // in the implementation of java.util.Random(), see link
long previous = 0;
void rseed(long seed) {
previous = seed;
}
long rand() {
long r = a * previous + c;
// Note: typically, one chooses only a couple of bits of this value, see link
previous = r;
return r;
}
Hai ancora bisogno di seminare questo generatore con un certo valore iniziale. Questo può essere fatto eseguendo una delle seguenti operazioni:
- Utilizzando qualcosa come l'ora corrente (bene nella maggior parte dei casi non critici per la sicurezza come i giochi)
- Utilizzando hardware rumore (buono per casualità critici per la sicurezza)
- Utilizzando un numero costante (buona per il debug, dato che si ottiene sempre la stessa sequenza)
- Se non è possibile utilizzare qualsiasi funzione e non si desidera utilizzare un seme costante, e se si utilizza un linguaggio che consente questo, è anche possibile utilizzare alcuni memoria non inizializzata. Ad esempio, in C e C++, definire una nuova variabile, non assegnargli alcunché e utilizzarne il valore per inizializzare il generatore. Ma notate che questo è ben lungi dall'essere un "buon seme" e solo un trucco per soddisfare le vostre esigenze. Non usare mai questo nel codice reale.
noti che non v'è alcun algoritmo che può generare diversi valori per differenti corre con gli stessi ingressi senza accesso ad alcune fonti esterne come l'ambiente di sistema. Ogni generatore di numeri casuali ben seminato fa uso di alcune fonti esterne.
Quindi qual è la tua fonte di casualità, allora? La maggior parte dei programmi sarà completamente deterministica se non è possibile utilizzare alcuna funzione esterna. –
Puoi chiarire cosa rende esattamente una funzione "esterna"? La matematica è una classe piuttosto elementare in java .. – Krease
@AndrewMao, anche le funzioni della libreria sono completamente deterministiche. Simulano una sequenza casuale senza esserne effettivamente una. La tua unica speranza di ottenere qualcosa di veramente casuale è affidarsi a una fonte esterna di casualità. –