[ _owl_ @ 22.07.2001. 23:17 ] @
Napisao sam mali program u c-u koji koristi funkciju rand().
Ono sto je zanimljivo je da mi program stalno daje iste brojeve.
napravio sam mali test i stalno dobijam iste rezultate.
Bez obzira kao koji user startujem program (a do sada sam ga startovao jedno 10 puta u toku 2-3 sata stalno sam dobijao iste brojeve , iako sam jedanput resetovo masinu).
Da li postoji nacin da "stvarno" dobijem slucajne brojeve?


[ Vojislav Milunovic @ 23.07.2001. 01:02 ] @
Ako oces bas slucajne brojeve koristi vreme...to se uvek menja
[ _owl_ @ 23.07.2001. 13:43 ] @
Da tek sad sam video da postoji srand(), ipak hvala na odgovoru.



Da li to znaci da ako se zna seed koji se da rand funkciji pre njenog

pozivanja mozemo predvideti sve brojeve koje ce ona dati (samo

napisemo program koji ce da koristi taj seed -- na istoj masini)





[ Vojislav Milunovic @ 23.07.2001. 13:59 ] @
Nisam gledao random i srand funkciju ali ako bas oces slucajne brojeve na UNIXu,moja preporuka je :

Code:

#include<sys/types.h>
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
int main(){
 int fd,rand;
 fd = open("/dev/urandom",O_RDONLY);
 read(fd,&rand,sizeof(int));
 printf("%dn",rand);
}

[ kajla @ 23.07.2001. 14:06 ] @
U Turbo C-u je postojala funkcija randomize(), tako:

randomize();
printf("%d\n",rand()%100 );

dobices talno razlicit rezultat.

poz.
[ _owl_ @ 24.07.2001. 00:15 ] @
ma ima i c funkciju rand() ali kao sto napisah ako vise puta startujes program koji je koristi dobices iste brojeve, npr:

for (i=0; i<1000; ++i)
{
nmb=rand();
printf("%dn", nmb);
}

daje stalno iste brojeve.
Predatore hvala za savet mislio sam da rand() koristi /dev/random.
[ Reljam @ 24.07.2001. 00:45 ] @
Citat:
_owl_ je napisao:
ma ima i c funkciju rand() ali kao sto napisah ako vise puta startujes program koji je koristi dobices iste brojeve, npr:

for (i=0; i<1000; ++i)
{
nmb=rand();
printf("%dn", nmb);
}

daje stalno iste brojeve.
Predatore hvala za savet mislio sam da rand() koristi /dev/random.


Evo kako se to radi - batali /dev/random - sporije je i nije portabilno:

Code:

srand( (unsigned)time( NULL ) );
[ tOwk @ 26.07.2001. 02:28 ] @
Ovde je problem zato što se koriste pseudo-slučajni brojevi.

Prema tome, ni rešenje sa upotrebom izlaza time() funkcije za seed nije dovoljno dobro, pošto se može lako predvideti. Zato je rešenje sa /dev/random najbolje, zato što ono omogućava upotrebu čak i spoljašnjih generatora slučajnih brojeva. Naravno, neki računari ih imaju ugrađene, pa ih treba i iskoristiti, ali "slučajni" brojevi dobijeni pomoću rand() funkcije ne treba koristiti ni za kakav ozbiljan posao.

Toliko.
[ Dejan Lozanovic @ 15.09.2001. 19:02 ] @
Citat:
tOwk je napisao:
Ovde je problem zato što se koriste pseudo-slučajni brojevi.

Prema tome, ni rešenje sa upotrebom izlaza time() funkcije za seed nije dovoljno dobro, pošto se može lako predvideti. Zato je rešenje sa /dev/random najbolje, zato što ono omogućava upotrebu čak i spoljašnjih generatora slučajnih brojeva. Naravno, neki računari ih imaju ugrađene, pa ih treba i iskoristiti, ali "slučajni" brojevi dobijeni pomoću rand() funkcije ne treba koristiti ni za kakav ozbiljan posao.

Toliko.


Pa sve zavisi kolika je periodicnost same random funkcije, nasao sam negde algoritam, ako se dobro secam na weirdowom sajtu, koji ima periodu 2^144, mislim da je to sasvim dovoljno i za neki ozbiljniji projekat.
Po meni random f-je i treba da daju iste rezultate sa istem seedom, radi prenosivosti same stvari. Jer u neku runu totalni random ste ipak u neku ruku stavili pod kontrolu. Evo sada i koda doduse malo sam ga doradio za svoje potrebe nekada davno :)



#ifndef __TSlucajni
#define __TSlucajni
#include <math.h>
#include <time.h>

class TSlucajni{
private:
float u[97], c, cd, cm;
int i97, j97;

public:
TSlucajni(int,int); //randomize
float Rnd(void); // interval [0,1)
inline int Ceo(int n ) // interval [0,n] celih
{return (n+1)*Rnd();}
int Interval(int,int); // interval celih [a,b]
float Interval(float,float); // interval realnih [a,b)
};
/*
randomize1
----------
* Ovo je inicijalizaciona rutina za generator slucajnih brojeva: rnd1
* Seed varijable moraju uzimati sledece opsege vrednosti:
0 <= IJ <= 31328
0 <= KL <= 30081
t Za proveru random generatora: uzeti IJ = 1802 & KL = 9373. Zatim treba
generisati 20 000 slucajnih brojeva. Sledecih sest brojeva pomnoženih sa
4096*4096 bi trebalo da budu:
6533892.0 14220222.0 7275067.0 6172232.0 8354498.0 10633180.0 */


TSlucajni::TSlucajni (int ij=time(0)%31328, int kl=time(0)%30081)
{
float s, t;
int i, j, k, l, m;
int ii, jj;

i = fmod(ij/177.0, 177.0) + 2;
j = fmod(ij , 177.0) + 2;
k = fmod(kl/169.0, 178.0) + 1;
l = fmod(kl , 169.0);

for (ii=0; ii<=96; ii++ )
{
s = 0.0;
t = 0.5;
for (jj=0; jj<=23; jj++ )
{
m = fmod( fmod(i*j,179.0)*k , 179.0 );
i = j;
j = k;
k = m;
l = fmod( 53.0*l+1.0 , 169.0 );
if ( fmod(l*m,64.0) >= 32)
s = s + t;
t = 0.5 * t;
}
u[ii] = s;
}

c = 362436.0 / 16777216.0;
cd = 7654321.0 / 16777216.0;
cm = 16777213.0 / 16777216.0;

i97 = 96;
j97 = 32;

return;
}

/*
rnd1
----
* Generator slucajnih brojeva u opsegu: [0-1)
* Ovo je NAJBOLJI dostupni generator slucajnih brojeva. Prolazi SVE testove
za generatore slucajnih brojeva i ima periodu od 2^144 (!). Da bi dao
ispravne rezultate mantise u float point prikazu brojeva moraju biti
najmanje 24 bitne. Pokazuje izuzetnu stabilnost pri ogromnim serijama.
To sam proverio testom Romanovskog za najmanje 10^8 generisanih brojeva.
* Zapazi da su JEDINE matematicke operacije sabiranje i oduzimanje
(iako ima i float-pointing matematike)->BRZINA! */

float TSlucajni::Rnd(void)
{
float uni;

uni=u[i97]-u[j97];
if (uni < 0.0) uni+=1.0;
u[i97]=uni;
i97--;
if (i97 < 0) i97=96;
j97--;
if (j97 < 0) j97=96;
c-=cd;
if (c < 0.0) c+=cm;
uni-=c;
if (uni < 0.0) uni+=1.0;
return (uni);
}

int TSlucajni::Interval(int a,int b){
if( a == b ) return a;
else if(a>b) {int c=a;
a=b;b=c;
}
return a+Ceo(b-a);
}

float TSlucajni::Interval(float a, float b){
if( a == b ) return a;
else if(a>b) {float c=a;
a=b;b=c;
}
return a+(b-a)*Rnd();
}


#endif

[ random @ 16.09.2001. 14:26 ] @
A jel si probao sa random() i srandom() umesto rand() i srand(), vrlo su malo sporije, a bolje se ponaaju...

iseak iz random(3):

DESCRIPTION
The random() function uses a non-linear additive feedback random number
generator employing a default table of size 31 long integers to return
successive pseudo-random numbers in the range from 0 to (2**31)-1. The
period of this random number generator is very large, approximately
16*((2**31)-1).

The random() and srandom() functions have (almost) the same calling
sequence and initialization properties as the rand(3) and srand(3) func-
tions. The difference is that rand(3) produces a much less random
sequence -- in fact, the low dozen bits generated by rand go through a
cyclic pattern. All the bits generated by random() are usable. For
example, `random()&01' will produce a random binary value.

Pored toga, /dev/random treba koristiti samo u sluaju da aplikacija ne koristi velike koliine sluajno generisanih brojeva, u suprotnom treba koristiti /dev/urandom() (videti random(4))...
[ BigFoot @ 16.10.2001. 20:57 ] @
Citat:
_owl_ je napisao:
Napisao sam mali program u c-u koji koristi funkciju rand().
Ono sto je zanimljivo je da mi program stalno daje iste brojeve.
Da li postoji nacin da "stvarno" dobijem slucajne brojeve?

Ne. "Stvarno" slucajne brojeve ne mozes dobiti. Uvek su to pseudo-slucajni brojevi, ali su toliko "slucajni" da je to uglavnom dovoljno. Jedino mozes nesto uraditi po pitanju toga da eventualno imaju normalnu raspodelu, ako ti to znaci.
[ Dejan Lozanovic @ 20.10.2001. 11:46 ] @
Citat:
BigFoot je napisao:
Citat:
_owl_ je napisao:
Napisao sam mali program u c-u koji koristi funkciju rand().
Ono sto je zanimljivo je da mi program stalno daje iste brojeve.
Da li postoji nacin da "stvarno" dobijem slucajne brojeve?

Ne. "Stvarno" slucajne brojeve ne mozes dobiti. Uvek su to pseudo-slucajni brojevi, ali su toliko "slucajni" da je to uglavnom dovoljno. Jedino mozes nesto uraditi po pitanju toga da eventualno imaju normalnu raspodelu, ako ti to znaci.

Ili eventuolno da se napravi neki hardverski uredjaj pa bi imao totalni random, pade mi na pamet mogao bi da pokupis sum sa muzicke karte i njega da koristis kao random
[ Ivan Dimkovic @ 20.10.2001. 11:54 ] @
Neki procesori vec imaju slicnu stvar - meri se temperatura procesora i na osnovu varijacije se mogu generisati prilicno random brojevi - a i sum je dobra ideja :)