Kezdőoldal » Számítástechnika » Programozás » C hibás véletlen-szám generálás?

C hibás véletlen-szám generálás?

Figyelt kérdé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:

[link]

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?


2018. okt. 28. 14:03
1 2
 11/12 anonim ***** válasza:

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.

2018. okt. 28. 18:40
Hasznos számodra ez a válasz?
 12/12 A kérdező kommentje:
Arra kellett rájönnöm, hogy már teljesen elfelejtettem ezt a modulos véletlen-szám generálást, ebben a pillanatban azt sem értem, hogy azzal miért tudtam generálni, de nem baj, a megoldásod előrevitt! Köszönöm szépen!
2018. okt. 28. 21:12
1 2

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

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!