Newsgroup: it.comp.lang.c++
Titolo: RAND()...solo questa?

La funzione rand() produce valori randomici fino a 65536 se non sbaglio...
La mia domanda č la seguente: esiste una funzione in C++ in grado di
produrre valori randomici dell'ordine del milione o miliardi?
Grazie
Ciao

 produrre valori randomici dell'ordine del milione o miliardi?
rand() produce numeri random (scusa il tuo termine non mi piace) tra 0 e
RAND_MAX.
RAND_MAX al limite vale 32767 piu' facilmente che 65536.
La soluzione e' scaricare una delle tante librerie, funzioni, etc.. che
implementano un generatore di numeri pseudo random alternativo (e nella
maggior parte dei casi migliore) rispetto a rand().
Tommy

 ha scritto nel messaggio
news:b5vvut$n2d$1...@hercules.btinternet.com...


 Mi sai indicare dove scaricare queste funzioni? Sono free? Spero di si...
:)
Credo che anche la ottima libreria boost (
http://www.boost.org/
) abbia
qualche cosa di valido:
http://www.boost.org/libs/random/
Ad ogni modo ti basta una ricerca con google. Io ho scaricato parecchie
librerie 3rd party, ma mai una per numeri random. Mi sono sempre
accontentato di rand(). Tuttavia se uno sviluppa applicazioni che si basano
sulla "qualita'" di questi numeri, beh, ammetto che rand() non e' il massimo
ed e' per questo che ho sentito parlare di molte librerie che implementano
funzioni alternative a rand(). Non mi ricordo quali. Fai una ricerca. Prima
pero' guarda se quella di boost fa al caso tuo.
Sono sicuro che se qualche altro membro di questo NG che ha avuto esperienza
con queste cose si interessasse a questo thread potrebbe consigliarti
qualche libreria in particolare. Io purtroppo ti posso solo dire che
esistono e puoi cercarle, scaricarne un paio e vedere quale ti piace di
piu'!
Tommy

 RAND_MAX al limite vale 32767 piu' facilmente che 65536.
Tra l'altro penso che la maggior parte dei compilatori recenti
abbia una rand che arriva a 31 bit e non solo a 15.
Comunque se ha fretta, tanto per fare delle prove,
puo' farsi un numero rand piu' lungo (30 bits) cosi':
int r1=(rand()>>2)&1023;
int r2=(rand()>>2)&1023;
int r3=(rand()>>2)&1023;
cioe' si fa 3 numeri di 10 bit casuali scartando i primi e gli ultimi
dati dalla funzione rand();
e poi li mette insieme:
int rrr = r1 | (r2<<10) | (r3<<20);
ciao
g

 ha scritto nel messaggio
news:b5vvut$n2d$1...@hercules.btinternet.com...
|

domanda: come si valuta la qualità del "random"? rand() non è vario nelle
sequenze di casuali?
curiosità.
ivan

 sequenze di casuali?
Lasciami dire che quando si dice che rand() non e' buona... e' una questione
controversa:
Lo standard C dice che:
<QUOTE>
The C89 Committee decided that an implementation should be allowed to
provide a rand function
which generates the best random sequence possible in that implementation,
and therefore mandated
no standard algorithm. It recognized the value, however, of being able to
generate the same 30
pseudo-random sequence in different implementations, and so it published as
an example in the
Standard an algorithm that generates the same pseudo-random sequence in any
conforming implementation, given the same seed.
</QUOTE>
Ad ogni modo la commissione fornisce un "esempio" di come questa funzione
potrebbe essere implementata:
unsigned long next=1;
int rand(void)
{
    next = next*1103515245 + 12345;
    return (unsigned int)(next/65536) % 32768;
}
void srand(unsigned int seed)
{
    next=seed;
}
La funzione esempio rand() e' banale e semplice, ma e' un buon esempio, solo
un esempio.
rand() produce sequenze uguali ogni volta se passi lo stesso seed. Questo e'
lo svantaggio. Il vantaggio e' che e' molto veloce.
Il problema e' che molti implementatori di compilatori prendono questa
funzione e cercano di migliorarla ed invece non producono risultati
abbastanza validi.
Molti programmatori (e anche io per fare in fretta) per fare numeri casuali
da 1 a 10 scrivono:
j=1+(rand() % 10);
Questo produce pessimi risultati visto che usa i low-order-bits.
meglio:
j=1+(int) (10.0*rand()/(RAND_MAX+1.0));
Faccio fatica a spiegarti bene e poi non so se vale la pena di perdere tempo
o meno, magari non ti interessa nemmeno nel dettaglio. Nel caso ti
interessasse leggiti :
http://csi.usc.edu/Courses/Weber.EE535/notes/chap07.pdf
Vedrai che qua trovi tutto quello che ti serve.
Tommy

 wrote
ho dimenticato il punto controverso:
In C dipende dal compilatore.... potrebbe essere implementata molto bene o
molto male (il C++ non credo aggiunga altro).
Nella maggior parte dei casi si puo' fare di meglio, putroppo spesso e
volentieri a scapito della velocita'!
Tommy

 volentieri a scapito della velocita'!
Il VC++ fa un buon lavoro, ma chiedendo 10.000.000 di numeri casuali nel
range 0-4999.
e risultato che il valore in tale range che esce piu' volte esce ben 2290
volte. Quello che esce meno 1669.
Con la funzione che ti ho dato, quella esempio dello standard C, il valore
che esce piu' volte esce 2311 e quello che esce meno 1689.
Come vedi le due funzioni si comportano i modo simile. Ovviamente piu'
vicini sono i due valori meglio e'!
Questa e' solo una delle caratteristiche che devono avere i generatori di
numeri pseudo casuali. Ci sono molti altri fattori da prendere in
considerazione. Guardati il PDF di cui ti ho dato il link.
Tommy

 volte. Quello che esce meno 1669.
Questo risultato e' nella norma fisiologica e penso che sia inevitabile
se uno sta realmente generando dei numeri casuali e non dei numeri
"che devono apparire lo stesso numero di volte".
Il punto e' che se tu generi dei numeri veramente casuali (o una
buona approssimazione di numeri casuali) allora non ti devi/puoi
aspettare che siano perfettamente equidistribuiti, ma solo
che siano equiprobabili.
Paradossalmente, se fossero perfettamente equidistribuiti, allora
non sarebbero veramente casuali, nel senso che ogni volta dovrebbe
uscire uno di quelli usciti di meno.
Ci sara' sempre un numero che esce di piu' e uno che esce di meno.
Sul lungo periodo il rapporto tra quello uscito di piu' e quello
uscito meno tendera' a 1, (come puoi verificare
ripetendo l'esperimento sopra per k*1000*1000 estrazioni, facendo
variare k tra 1 e 100) ma, in funzione del numero di estrazioni
e del numero di bin in cui si distribuiscono i numeri (5000 in questo
caso) ci si puo' aspettare sempre una certa discrepanza (che tendera',
valutata relativamente e non in modo assoluto) a 0, ma che per valori
"piccoli" come 1 milione di estrazioni e grandi come 5000 bin,
e' abbastanza rilevante. (Prova a vedere come cambia il rapporto
tra massimo e minimo usando 500 bin invece di 5000).
ciao,
g.

 tra massimo e minimo usando 500 bin invece di 5000).
Non di molto e poi io il test lo facevo su 10.000.000 numeri nel range
0-4.999 e non 1.000.000 di numeri.
Tommy

 potrebbe essere implementata:
L'esempio fornito dalla commissione è decisamente mediocre
e funziona in modo accettabile solo per sequenze relativamente
corte (<30000 numeri), poi comincia a mostrare una correlazione
piuttosto forte.


gpg public key available from 
www.keyserver.net
, Key ID 0x377FE07F
Key fingerprint = B446 7332 ED55 BC68 5FE8  DE0F 98DF EC86 377F E07F