Come posso generare un numero casuale compreso tra 0 e n dove n può essere> RAND_MAX in c, C++?generando un numero casuale compreso tra 0 e n dove n può essere> RAND_MAX
Grazie.
Come posso generare un numero casuale compreso tra 0 e n dove n può essere> RAND_MAX in c, C++?generando un numero casuale compreso tra 0 e n dove n può essere> RAND_MAX
Grazie.
Do x numeri casuali (da 0 a RAND_MAX) e aggiungere insieme, dove
x = n% RAND_MAX
Le probabilità non contano affatto? –
Sono d'accordo con @Sinan, questo distrugge la distribuzione casuale. –
e tuttavia una versione meno descrittiva di questa risposta è la risposta più votata. Devo amare COSÌ. Distruggerebbe comunque solo la distribuzione, ma sarebbe molto meno casuale quando x è molto grande. come x -> infinito vedresti finalmente un numero completamente non casuale, ma mi piacerebbe pensare a una situazione in cui sarebbe necessario un numero casuale superiore a 10 milioni. –
contempla la generazione in due fasi, quindi combinare i numeri risultanti.
Penso che la comunità di matematica di sci.crypt.random-number possa avere problemi con la casualità di quello. –
Previsione facile. Hanno anche problemi con la casualità di una singola chiamata. :) – MSalters
Assumendo C++, hai provato a guardare una discreta libreria di numeri casuali, come Boost.Random. Altrimenti potrebbe essere necessario combinare più numeri casuali.
Ci sono molti modi per farlo.
Se si sta bene con meno granularità (maggiore possibilità di duplicazione), quindi qualcosa come (in pseudocodice) rand() * n/RAND_MAX
funzionerà per diffondere i valori su un intervallo più ampio. Il problema è che nel tuo codice reale dovrai evitare l'overflow, sia tramite casting rand() o n per un tipo abbastanza grande (es. Int 64-bit se RAND_MAX è 0xFFFFFFFF) per mantenere il risultato della moltiplicazione senza overflow, o utilizzare un'API moltiplicatore-diviso (come MulDiv64 di GNU o MulDiv di Win32) ottimizzata per questo scenario.
Se si desidera ottenere la gran quantità su ciascun numero intero, è possibile chiamare rand() più volte e aggiungere i risultati. Un'altra risposta suggerisce di chiamare rand() per ogni blocco a 8-bit/16-bit/32-bit in base alla dimensione di RAND_MAX.
Ma, IMHO, le idee di cui sopra possono diventare rapidamente complicate, inaccurate o entrambe. La generazione di numeri casuali è un problema risolto in altre librerie ed è probabilmente molto più semplice prendere a prestito il codice esistente (ad esempio da Boost) piuttosto che provare a eseguire il rollover. Open source random number generation algorithm in C++? ha risposte con più collegamenti se desideri qualcosa oltre a Boost.
[EDIT: revisione dopo una giornata impegnativa ... intendeva tornare indietro e ripulire la mia risposta veloce stamattina, ma mi sono tirato indietro e sono tornato solo ora. :-)]
Ti manca un cast importante in là. –
@Justin 'rand' restituisce un' int'. Supponendo che 'n' sia anche un tipo intero e dato che' RAND_MAX' è un numero intero, non otterrai affatto molta casualità dal tuo metodo. –
sì, volevo tornare a rivedere la mia nota troppo vaga e fuorviante sul casting per rendere più chiaro che era necessario un cast di tipo se RAND_MAX * n> 0xFFFFFFFF, ma mi sono occupato e non ce l'ho fatta fino ad ora per aggiornare. grazie per avermi tenuto in punta di piedi! –
supponiamo che si desidera generare un numero casuale a 64 bit, si potrebbe fare questo:
uint64_t n = 0;
for(int i = 0; i < 8; ++i) {
uint64_t x = generate_8bit_random_num();
n = (n << (8 * i)) | x;
}
Naturalmente si potrebbe farlo 16/32 bit alla volta di troppo, ma questo illustra il concetto.
Come si generano quei numeri casuali 8/16/32-bit dipende da voi. Potrebbe essere semplice come rand() & 0xff
o qualcosa di meglio a seconda di quanto ti interessa della casualità.
La domanda diventa quanto casuale sono gli ultimi 8 bit di un valore da rand()! Sospetto che non sia così casuale come pensi. –
@Martin: più specificatamente, la domanda diventa quanto correlato gli 8 bit inferiori di rand() sono tra le chiamate. –
@ Martin: è per questo che ho scritto 'generate_8bit_random_num();' invece di 'rand() & 0xff' nel mio esempio principale. Vale la pena notare che la funzione 'rand' di gnu-glibc ha una buona casualità nei byte bassi. Realmente costruiscono il numero casuale per fasi e assemblano il risultato. –
Considerare una variabile casuale che può assumere valori {0, 1}
con P(0) = P(1) = 0.5
. Se si desidera generare valori casuali tra 0
e 2
sommando due disegni indipendenti, si avrà P(0) = 0.25
, P(1) = 0.5
e P(2) = 0.25
.
Pertanto, utilizzare una libreria appropriata a meno che non ci si interessi del PDF dell'RNG.
Vedere anche il capitolo 7 in Numerical Recipes.(Questo è un collegamento all'edizione precedente ma è quello che ho studiato comunque ;-)
Se stai cercando una distribuzione uniforme (o qualsiasi distribuzione per quella modalità), devi fare attenzione che le proprietà statistiche di l'output è sufficiente per le tue esigenze. Se non puoi usare direttamente l'output di un generatore di numeri casuali, dovresti fare molta attenzione nel cercare di combinare i numeri per raggiungere i tuoi bisogni.
Al minimo è necessario assicurarsi che la distribuzione sia appropriata. Se siete alla ricerca di una distribuzione uniforme di numeri interi da 0 a M, e si dispone di qualche uniforme generatore di numeri casuali g()
per produrre uscite che sono più piccoli di M, assicuratevi di fare non eseguire una delle seguenti operazioni:
Oltre a ciò, v'è il potenziale di cross-correlazione tra i termini della sequenza (generatori di numeri casuali dovrebbero produrre identically- indipendente uscite distribuite).
Leggi l'arte della Programmazione del computer vol. 2 (Knuth) e/o Ricette numeriche e porre domande fino a quando non ti senti sicuro.
I numeri casuali sono un argomento molto specializzato che, a meno che tu non sia un esperto di matematica, è molto facile sbagliare. Quindi consiglierei di non creare un numero casuale da più fonti, nel caso in cui utilizzi una buona libreria.
avrei primo sguardo a boost::Random
Se questo non è prova suffecient di questo gruppo sci.crypt.random-numbers porre la domanda non ci dovrebbero essere in grado di aiutare.
Se l'implementazione ha un tipo intero abbastanza grande da contenere il risultato si ha bisogno, è generalmente più facile per ottenere una distribuzione decente, semplicemente utilizzando un generatore che produce la gamma richiesto che cercare di combinare le uscite dal generatore più piccolo .
Naturalmente, nella maggior parte dei casi, è sufficiente scaricare il codice per qualcosa come il Mersenne Twister o (se hai bisogno di un generatore di qualità crittografico) Blum-Blum-Shub e dimenticarti di scriverne uno tuo.
Quale distribuzione? –
C e C++ ti danno risposte diverse, che cos'è? Ad esempio, in C++ è possibile utilizzare la libreria casuale di boost. – GManNickG
Check out: http://groups.google.com/group/sci.crypt.random-numbers/topics?lnk=rgr –