PDA

View Full Version : [C]algoritmo c per generare random,evitando la funzione rand()


santaclause83
17-10-2007, 14:32
la funzione rand() di c mi dà un problema anomalo se la inserisco in un determinato blocco del progetto..

ho provato a farmi una funzione che genera numeri random ma ho un pò arrangiato quello che mi ricordavo da un codice visto in passato,adesso il programma gira,ma l'algoritmo non è corretto

...qualcuno saprebbe dirmi se conosce un algoritmo più preciso di questo?..oppure dei link utili a riguardo


unsigned int nn = 4545;

float random() {

nn = (nn*12345 +1) & 0X7fff;

return (float) nn/0X7fff;

}

grazie!

recoil
17-10-2007, 14:43
come fa ad essere random sta funzione? parti da una costante, ti darà sempre lo stesso risultato...

se vuoi un qualcosa di più casuale intercetta in qualche modo l'ora di sistema e usala come base per qualche calcolo che restituisca il range di valori corretto. almeno sei sicuro che due esecuzioni del programma daranno con buona probabilità due risultati diversi

santaclause83
17-10-2007, 14:55
no asp,considera che l'inizializzazione fuori viene fatta una volta sola,poi la funzione viene chiamata a ripetizione da una callback..

ho visto un algoritmo simile ma non ricordo bene com'era esattamente..se avete idee a riguardo fate sapere,grazie!

Guille
17-10-2007, 15:02
no asp,considera che l'inizializzazione fuori viene fatta una volta sola,poi la funzione viene chiamata a ripetizione da una callback..

ho visto un algoritmo simile ma non ricordo bene com'era esattamente..se avete idee a riguardo fate sapere,grazie!

Si ma se l'inizializzazione è una costante ogni volta che eseguirai l'applicazione genererai sempre la stessa sequenza di numeri.

trallallero
17-10-2007, 15:10
Si ma se l'inizializzazione è una costante ogni volta che eseguirai l'applicazione genererai sempre la stessa sequenza di numeri.

infatti basta fare:
nn = time(NULL);
e risolvi il problema

cionci
17-10-2007, 16:15
Ci sono libri e libri sulla generazione di sequenze pseudo-random. Con algoritmi fatti in casa, a meno che tu non sia un matematico (o qualcuno che ha studiato la materia), difficilmente riuscirai ad ottenere qualcosa di valido.
Ad esempio...la prima cosa che mi viene in mente è che quell'algoritmo possa essere convergente ad un determinato valore.

yorkeiser
17-10-2007, 17:34
Mmh ad occhio convergente direi di no, forse puoi avere problemi di periodicità visto che usi un and binario... In qualsiasi caso, come è stato già detto, per ottenere una sequenze pseudocasuale devi comunque partire da un seed generato casualmente (ad esempio mediante l'orologio di sistema), non puoi partire da una costante, pena riottenere ogni volta sempre la stessa sequenza

Ziosilvio
17-10-2007, 18:05
la funzione rand() di c mi dà un problema anomalo se la inserisco in un determinato blocco del progetto
Che problema, e quale blocco?

Forse puoi trovare qualche idea QUI (http://www.hwupgrade.it/forum/showthread.php?t=1196677).

cionci
17-10-2007, 18:19
Mmh ad occhio convergente direi di no, forse puoi avere problemi di periodicità visto che usi un and binario...
Prova ad avere nn == 0 ;) Non è impossibile visto che nn viene da un and ;)

Perry_Rhodan
17-10-2007, 22:00
cerca l'algoritmo del marsenne twister o una libreria che lo implementi, è ritenuto uno degli algoritmi migliori per generare numeri pseudocasuali.

la funzione rand() lasciala perdere ;)

http://random.mat.sbg.ac.at/generators/


se ti servono numeri casuali:

http://www.random.org/

yorkeiser
18-10-2007, 09:47
Prova ad avere nn == 0 ;) Non è impossibile visto che nn viene da un and ;)

Effettivamente il dubbio c'era, ma in fondo non convergerebbe neanche lì: questi sono i primi 20 rand() generati a partire da un seed uguale a 0

0.000000
0.000031
0.376782
0.225929
0.002564
0.646168
0.705527
0.463851
0.063723
0.632130
0.405347
0.854122
0.808496
0.582934
0.101260
0.021699
0.861843
0.123569
0.418287
0.591662
0.848781


Questo grazie al +1 nella formula, altrimenti effettivamente convergerebbe a 0.
Futili disquisizioni matematiche ovviamente ;)

cionci
18-10-2007, 11:03
In effetti ;)

Lyane
18-10-2007, 12:04
Prova questa:


#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define S1MAX 2147483562
#define S2MAX 2147483398

float Rand(void);
void Srand(void);

long s1,s2;

void main(void)

{
int i;

Srand();

for(i=0;i<256;i++)
printf("%7.2f\n",Rand());
}

void Srand(void)

{
time_t t;

s1=(unsigned)time(&t);
s2=s1*s1;

if(s1<1||s1>S1MAX)
s1=(abs(s1)%S1MAX)+1;
if(s2<1||s2>S2MAX)
s2=(abs(s2)%S2MAX)+1;

}

float Rand()

{
long Z,k;

k=s1/53668;
s1=40014*(s1-k*53668)-k*12211;
if(s1<0)
s1+=S1MAX+1;

k=s2/52774;
s2=40692*(s2-k*52774)-k*3791;
if(s2<0)
s2+=S2MAX+1;

Z=s1-s2;
if(Z<1)
Z+=S1MAX;

return(Z*4.656613E-10);
}