C hibás véletlen-szám generálás?
Van egy eléggé komplex kódom, amiben hiba van és nem jövök rá, hogy mi az. Az egész a véletlen-számokra épül. Az egyik alapeloszlásban van egy törés, aminek nem kellene ott lennie. Emiatt megnéztem egy sima egyenletes eloszlást, ahol talán még én sem hibázhattam és ott is van egy ugrás... Nézzétek meg kérlek:
for (int i=0; i<1000000000; i++) {
double A, B;
int D;
B=rand() % 10000000;
A=B/10000000.0;
D=floor(A*180.0);
test[D]+=1;
}
for(int i=0; i<180; i++)
{
fprintf(T, "%lf\n", test[i]);
}
Az eredmény:
Egyértelműen van benne egy ugrás, ami bár nem nagy, mégis okozhat hibát és egész biztosan nem kellene ott lennie. Vélemény? Mi lehet az oka?
Most tegyük fel, hogy a rand() függvény 1 és 5 között ad vissza számokat egyenletes eloszlás szerint. Hívogatod a rand() függvényt és veszed az eredményeket modulo 2.
Hány darab szám ad 0-t, 1-től 5-ig modulo 2? 2 db: 2, 4
Hány darab szám ad 1-t, 1-től 5-ig modulo 2? 3 db: 1, 3, 5
Ezért a modulo 2 képzésnél elveszted az egyenletes eloszlást, mert kicsit nagyobb eséllyel lesz az eredmény 1, mint 0.
A való életben a rand() 0 és RAND_MAX konstans között generál számokat, ahol RAND_MAX egy beépített konstans, ami az stdlib könyvtárból jön. Kódban is így hivatkozhatsz rá, hogy RAND_MAX. Ez nem az a szám, amit a modulo után írtál. Ha a rand() eredményét szeretnéd [0,1) közé képezni és megtartani az egyenletes eloszlást, akkor simán csak oszd el (RAND_MAX + 1.0)-val, és itt fontos a ".0" rész, hogy integer helyett lebegőpontos számokkal dolgozzon a program és így az eredmény is lebegőpontos lesz integer helyett.
Tehát, ha a te gépeden a RAND_MAX véletlenül 15 millió és a rand() erdeményét modulo 10 millió veszed, akkor mi történik? 0 és 15 millió között van 4 db 5 millióval osztható (0, 5M, 10M, 15M), de csak 2 db (10 millió - 1)-el osztható szám (0 és 10M-1). Tehát, ha továbbra is moduloval képzed le a számokat egy intervallumba, esetünkben [0, 10 millió) (a % 10 millió miatt), akkor nagyobb eséllyel esik az eredmény az 5 millió helyére, mint a (10 millió - 1) helyére.
Kapcsolódó kérdések:
Minden jog fenntartva © 2025, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!