Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Salve a tutti!
Mi servirebbe per un progettino personale realizzare un ciclo che riempa totalmente un vettore bidimensionale. L'algoritmo per me non è un problema, di fatti in 2 o 3 minuti ho completato l'algoritmo principale senza problemi, però c'è un problema enorme che mi costringe ad arrestare questo piccolo progetto: la funzione rand() non è efficiente al 100%... Di fatti con un vettore bidimensionale 80x24 (1920 celle), ne riesce a riempire solamente 808, meno della metà...
Questo è l'algoritmo che ho sviluppato:
Che vuol dire? In che senso non e' "efficiente"? Non vedo come possa essere misurata l'efficienza della rand ...
Testo quotato
Di fatti con un vettore bidimensionale 80x24 (1920 celle), ne riesce a riempire solamente 808, meno della metà...
Ancora ... cosa vuoi dire? Sicuramente non hai adottato un corretto algoritmo ...
Efficiente nel senso che se voglio che si presenti un numero da 0 a 9999, è vero che la funzione rand mi restituisce dei numeri in quel range, ma non mi permette di riuscire a darmi tutti e i 10000 numeri ma solo ad esempio 2000... Nel caso del mio programma, vengono inizializzate 1920 celle col valore 0, e che devono essere riempite una ad una casualmente col valore 1, solo che siccome il rand non riesce a farmi uscire determinati numeri allora non tutte le celle vengono riempite, ma solo 808. E penso che il mio algoritmo è perfetto
wow, funziona in maniera perfetta O_O. Il problema a quanto pare stava nell'azzerare la variabile v. Poi anche togliendo l'srand, il tutto funziona con success. Comunque grazie
Postato originariamente da xeeynamo: Efficiente nel senso che se voglio che si presenti un numero da 0 a 9999, è vero che la funzione rand mi restituisce dei numeri in quel range, ma non mi permette di riuscire a darmi tutti e i 10000 numeri ma solo ad esempio 2000... Nel caso del mio programma, vengono inizializzate 1920 celle col valore 0, e che devono essere riempite una ad una casualmente col valore 1, solo che siccome il rand non riesce a farmi uscire determinati numeri allora non tutte le celle vengono riempite, ma solo 808. E penso che il mio algoritmo è perfetto
Questa tua risposta mi ha fatto venire un dubbio, perchè, in realtà, la rand() permette di generare solo numeri pseudocasuali...
Mi sono chiesto: se genero un numero di valori molto grande, come si comporta ? Riuscirà a generare tutti i valori del range per un numero di prove molto grande ?
Ho, quindi, fatto un programmino, per controllare se salta qualche valore del range:
cout<< i <<", "<<(unsignedint) valoriGenerati.count(i)<< endl;
return0;
}
Il programma è semplice: dato un range e un numero di prove, genera range*numero di prove numeri casuali e li inserisce in un multiset. Al termine stampa l'occorrenze dei valori nel range (in formato csv).
Ho importato il csv su calc e ho calcolato la media ponderata dei valori, nonchè un grafico:
Con range 100, numero di prove 30 (per un totale complessivo di 300 generazioni) ho ottenuto media 50,18.
Allego il grafico.
I risultati credo che parlino da soli (non ho provveduto a fare calcoli extra o a scomodare la gaussiana perchè è palese che il funzionamento della rand è accettabile).
leggendo questa discussione mi è venuta in mente una vecchissima questione riguardo la generazione dei numeri pseudo-casuali....
Ammettiamo di voler generare i numeri compresi nel range 0-99.
La soluzione spontanea al problema sarebbe rand() % 100. Cioè, prendo un numero casuale, lo divido per 100, prendo il resto e sicuramente il risultato sarà compreso tra 0 e 99...
Concettualmente non fa una grinza, ma c'è una cosa che non funziona.
I numeri generati da rand() sono interi a 32 bit (dipende dalla macchina ovviamente). Questo significa che il range "nativo" della funzione è da 0 a 4294967295 (2^32 - 1, con l'aiuto della calcolatrice).
Se dividessimo per 100 tutti i numeri del range, e considerassimo i resti, vedremmo che (alla fine del conto) ci fermeremmo al numero 95. Quindi in totale, mancheranno all'appello un 96, un 97, un 98 e un 99 per pareggiare i conti. In termini matematici, le classi modulo [96], [97], [98] e [99] hanno un elemento in meno rispetto alle precedenti 96 classi (dalla classe [0] alla classe [95]). Quindi tirando a sorte, i numeri 96,97,98 e 99 avrebbero meno probabilità di essere pescati rispetto agli altri.
Ecco perchè in campo finanziario (quando si devono generare numeri casuali per chiavi crittografiche nelle transazioni bancarie) si usano metodi più precisi per generare numeri casuali.
Un metodo migliore è quello di generare un numero a 32 bit, elevarlo al quadrato (diventando così di 64 bit), scartare i primi 16 bit e gli ultimi 16 bit prendendo così in considerazione i soli 32 bit centrali, e usando questi ultimi per generare i numeri che ci interessano.
Questo metodo funziona perchè, e potete verificarlo con carta e penna, le cifre centrali di una moltiplicazione (in questo caso moltiplicazione per se stesso), sono quelle che vengono influenzate sia dalle cifre a destra che dalle cifre a sinistra degli operandi, eliminando il problema della "scarsità" degli elementi 96, 97, 98 e 99.
Ovviamente il ragionamento è applicabile a qualunque range generico. Fanno eccezione i range potenze di 2, perchè in questo caso si tratta di sottomultipli esatti del range nativo e quindi non esistono disparità tra le classi modulari (cioè i gruppi di numeri) che ci interessano.
(stasera mi sento in vena di filosofeggiare... hihihi)