Come funziona il generatore di numeri casuali? (ad esempio in C/C++ Java)Come funziona un generatore di numeri casuali?
Come posso scrivere il mio generatore di numeri casuali? (Per esempio in C/C++ Java)
Come funziona il generatore di numeri casuali? (ad esempio in C/C++ Java)Come funziona un generatore di numeri casuali?
Come posso scrivere il mio generatore di numeri casuali? (Per esempio in C/C++ Java)
ho trovato questo uno per Java:
http://www.javamex.com/tutorials/random_numbers/java_util_random_algorithm.shtml
googling how random functions work java
Sono sicuro che la risposta è specifico per la lingua, ma si può prova a modificare la mia query di Google per la lingua di tua scelta.
Come ho fatto in passato, ottenevo un valore dal sistema che cambia molto rapidamente, ad esempio il timer del sistema in millisecondi.
La prossima cosa che dovete fare è applicare qualche formula che genererà un nuovo numero da questo numero "ingresso" e agganciarlo alla gamma è necessario, ad esempio 0..255:
random_number = intero (formula (valore del timer)) MOD 255
In questo modo, si ha un nuovo numero "casuale" ogni volta che si chiama la funzione.
Un esempio funzione formula potrebbe essere:
formula (x) = ((x XOR costante) + constant2) gamma MOD
XOR usato essere uno dei miei preferiti.
Aggiornamento: mi rendo conto che questa formula è una pessima uno, genera un insieme abbastanza prevedibile di numeri. Inoltre, il timer di sistema è troppo prevedibile come sorgente. Quindi per la maggior parte delle applicazioni, questo non è sufficiente. Se hai bisogno di casualità migliore, usa più fonti del solo timer di sistema e better formulas per combinarle.
Un timer millisecondo non è un sistema che cambia rapidamente, per la maggior parte degli scopi di calcolo è un numero semi-fisso, che cambia di tanto in tanto. E quando cambia, cambia in termini completamente prevedibili. Nel migliore dei casi il tempo dovrebbe essere usato come seme e solo una volta ogni tanto per assicurarsi che il tempo sia cambiato completamente prima di riutilizzarlo. Quindi meglio di un timer è un sistema che cambia * veramente * rapidamente e non predittivo. – daramarak
Buon commento. Ho cercato di menzionare questo disclaimer in "Aggiornamento". – thomaspaulb
Una delle cose da tenere a mente è che non ci sono generatori di numeri casuali "veri". Si limitano a generare numeri che lo guardano allo in modo casuale a noi comuni mortali.
Uno degli esempi più semplici di questo (da implementare anche) è Linear congruential generator. Certo, i numeri sembrano imprevedibili per te e me, ma in realtà sono equamente distanziati all'interno di un campo finito.
Naturalmente alcuni generatori, come Blum Blum Shub non sono prevedibili per un estraneo, anche se applica seri compiti matematici e potenza di calcolo al compito, ma a livello fondamentale, i generatori di numeri casuali non sono casuali; sono regolari e prevedibili.
\ dev \ random è più casuale e puoi anche allegare qualcosa per misurare cose come la temperatura dell'aria esatta o un contatore geiger per più casualità. –
random.org :) .... – Shiki
Gli LCG non producono necessariamente output in * qualsiasi * campo finito, non importa di numeri equidistanti. –
Ci sono molte informazioni disponibili su come stanno funzionando ... leggi la risposta di Konamiman e usa google un po '.
Perché desideri scrivere un nuovo generatore casuale? Probabilmente non dovresti provare a farlo ... finché non avrai bisogno di qualcosa di molto speciale. Ad esempio in un gioco è possibile utilizzare uno shuffle bag che produce valori casuali "equi" - dare un'occhiata a this interesting question on SO.
ho posto questo qui, perché mi piaceva molto l'idea e l'attuazione quando ho letto per la prima volta :)
Ecco il codice per tirare i dadi si utilizza un generatore di numeri casuali io ho sviluppato il pad in questo valori RNG attesa esadecimale 15 in tutto
DIM pad(15) AS INTEGER
CLS
egg$ = "EFCDBA01457FA968"
ghh$ = egg$
nom% = 0
zen% = LEN(ghh$)
WHILE zen% > 0
opp$ = LEFT$(ghh$, 1)
eff% = ASC(opp$)
IF eff% >= 48 AND eff% <= 57 THEN eff% = eff% - 48 ELSE eff% = (eff% - 65) + 10
IF eff% > 15 THEN eff% = eff% - 32
pad(nom%) = eff%
nom% = nom% + 1
zen% = LEN(ghh$) - 1
ypp$ = RIGHT$(ghh$, zen%)
ghh$ = ypp$
WEND
sol& = 0
FOR zyx% = 0 TO 3
sol& = sol& * 16
sol& = sol& + pad(zyx%)
NEXT zyx%
sat% = sol& - 32768
RANDOMIZE sat%
FOR zyx% = 0 TO 15
PRINT HEX$(pad(zyx%));
NEXT zyx%
RANDOMIZE TIMER
respawn:
INPUT "sides per die"; die%
INPUT " number of dice"; dice%
INPUT "number to add to dice roll can be negative"; num%
INPUT "multiplier use 1 if so desired single precision floating point number"; g!
PRINT " hit any key to roll again with these values hit n for new values and q to quit"
PRINT " the number will be added or subtracted first before the multiplier takes effect"
reroll:
sum! = 0
FOR x% = 1 TO dice%
GOSUB rndmz
GOSUB demf
GOSUB drand
k% = INT(dr# * die%) + 1
sum! = sum! + k%
NEXT x%
sum! = (sum! + num) * g!
PRINT "you rolled a :"; sum!
i$ = ""
WHILE i$ = "": i$ = INKEY$: WEND
IF i$ = "n" THEN GOTO respawn
IF i$ = "q" THEN GOTO theend
GOTO reroll
theend:
SYSTEM
END
rndmz: rhet$ = ""
zum% = 0
FOR yxz% = 0 TO 15
FOR zyx% = 0 TO 15
IF zyx% MOD 3 = 0 THEN zum% = (zum% + pad(zyx%)) MOD 16
IF zyx% MOD 3 = 1 THEN zum% = (zum% + 16 - pad(zyx%)) MOD 16
IF zyx% MOD 3 = 2 THEN zum% = (zum% + INT(RND * 16)) MOD 16
NEXT zyx%
rhet$ = rhet$ + HEX$(zum%)
NEXT yxz%
ghh$ = rhet$
RETURN
demf: nom% = 0
zen% = LEN(ghh$)
WHILE zen% > 0
opp$ = LEFT$(ghh$, 1)
eff% = ASC(opp$)
IF eff% >= 48 AND eff% <= 57 THEN eff% = eff% - 48 ELSE eff% = (eff% - 65) + 10
IF eff% > 15 THEN eff% = eff% - 32
pad(nom%) = eff%
nom% = nom% + 1
zen% = LEN(ghh$) - 1
ypp$ = RIGHT$(ghh$, zen%)
ghh$ = ypp$
WEND
FOR zyx% = 0 TO 15
'PRINT HEX$(pad(zyx%));
NEXT zyx%
RETURN
drand: dr# = pad(0)
FOR eff% = 1 TO 15
dr# = dr#/16
dr# = dr# + pad(eff%)
NEXT eff%
dr# = dr#/16
RETURN
derf: a# = 1
x# = 1
b# = 1/(2^.5)
c# = .2500000000000011#
FOR u% = 1 TO 3
y# = a#
a# = (a# + b#)/2
b# = (b# * y#)^.5
c# = c# - x# * (a# - y#)^2
x# = 2 * x#
pi# = ((a# + b#)^2)/(4 * c#)
PRINT pi#
NEXT u%
pi# = pi# + .000000000000015#
PRINT pi#
questo qui alla fine calcola pi greco a quasi altrettanti luoghi possibili in soli 3 loop attraverso l'algoritmo dispiace che venga scritto in un linguaggio di base arcaica, è l'unico di programmazione linguaggio che conosco, potrebbe essere possibile portarlo su C++ o Java
Basta dare uno sguardo attento alla logica di questa e soprattutto attenzione alle procedure di priming o seeding/inizializzazione, che devono essere usate o che falliranno come un buon rng ... questo è uno che ho sviluppato per scopi di gioco dove avere enormi la sicurezza non è tanto di una preoccupazione come la velocità ...
c'è anche questo algoritmo:
Oh, e più seriamente:
generatori di numeri casuali usano formule matematiche a che trasferire uno o più numeri in un altro. Se, ad esempio, prendi un numero costante N
e un altro numero n_0
, e prendi il valore di n mod N
(l'operatore modulo), riceverai un nuovo numero n_1
, che sembra come se non fosse correlato a n_0
. Ora, ripeti la stessa procedura con n_1
e otterrai un altro numero. Quello che hai qui è un generatore (MOLTO CATTIVO) di numeri apparentemente casuali. Ricorda, il metodo che ho descritto qui è un metodo giocattolo che non dovrebbe essere usato per qualcosa di serio. Tuttavia, illustra il principio generale.
Ricorda:
Se tutti i lavori scientifici i cui risultati sono in dubbio a causa di cattive
rand
s dovessero scomparire dagli scaffali della biblioteca, non ci sarebbe un gap su ogni ripiano circa grande come il vostro pugno.
(parafrasato dal capitolo 7 di Numerical recipes). Questo è un testo da leggere per chiunque utilizzi generatori di numeri casuali per qualsiasi lavoro serio.
Questo non fornisce una risposta alla domanda. Per criticare o richiedere chiarimenti da un autore, lascia un commento sotto il loro post. – Eelke
Eelke: è meglio ora? –
Il problema con la casualità è che non si può mai essere sicuri, ma è possibile passare i numeri generati attraverso un test statistico (ricordo il test del chi-quadro dei miei giorni universitari) e ottenere una percentuale chiamata "grado di confidenza". Ma avrai probabilmente bisogno di più di sei nove consecutive per ottenere un risultato negativo :) –
È anche comune seminare questi tipi di generatori utilizzando qualcosa come il quinto decimale dell'orario corrente che appare anche casuale per noi. Aggiungi insieme input da alcuni sistemi caotici, ad es. dati meteo, dati del mercato azionario, ancora, usando modulo e hai buoni numeri seme.
possibili duplicati: http://stackoverflow.com/questions/1359318/how-does-random-actually-work, http://stackoverflow.com/questions/6593636/how-does-software-generate-random- number-and-how-do-these-compare-with-human-g –
Donald Knuth parla della generazione di numeri casuali nel primo volume del suo classico The Art of Computer Programming. Vorrei iniziare da lì. Beh, ho iniziato lì, molto tempo fa. :) –