c++ - What am i doing wrong with these random numbers? -
i've been told rand() mod n produces biased results, tried make code check it. generates s
numbers 1 l
, sorts occurrences.
#include <iostream> #include <random> using namespace std; struct vec_struct{ int num; int count; double ratio; }; void num_sort(vec_struct v[], int n){ (int = 0; < n-1; i++){ (int k = 0; k < n-1-i; k++){ if (v[k].num > v[k+1].num) swap(v[k], v[k+1]); } } } void count_sort(vec_struct v[], int n){ (int = 0; < n-1; i++){ (int k = 0; k < n-1-i; k++){ if (v[k].count < v[k+1].count) swap(v[k], v[k+1]); } } } int main(){ srand(time(0)); random_device rnd; int s, l, b, c = 1; cout << "how many numbers generate? "; cin >> s; cout << "generate " << s << " numbers ranging 1 to? "; cin >> l; cout << "use rand or mt19937? [1/2] "; cin >> b; vec_struct * vec = new vec_struct[s]; mt19937 engine(rnd()); uniform_int_distribution <int> dist(1, l); if (b == 1){ (int = 0; < s; i++){ vec[i].num = (rand() % l) + 1; } } else if (b == 2){ (int = 0; < s; i++){ vec[i].num = dist(engine); } } num_sort(vec, s); (int = 0, j = 0; < s; i++){ if (vec[i].num == vec[i+1].num){ c++; } else { vec[j].num = vec[i].num; vec[j].count = c; vec[j].ratio = ((double)c/s)*100; j++; c = 1; } } count_sort(vec, l); if (l >= 20){ cout << endl << "showing 10 common numbers" << endl; (int = 0; < 10; i++){ cout << vec[i].num << "\t" << vec[i].count << "\t" << vec[i].ratio << "%" << endl; } cout << endl << "showing 10 least common numbers" << endl; (int = l-10; < l; i++){ cout << vec[i].num << "\t" << vec[i].count << "\t" << vec[i].ratio << "%" << endl; } } else { (int = 0; < l; i++){ cout << vec[i].num << "\t" << vec[i].count << "\t" << vec[i].ratio << "%" << endl; } } }
after running code can spot expected bias rand():
$ ./rnd_test how many numbers generate? 10000 generate 10000 numbers ranging 1 to? 50 use rand or mt19937? [1/2] 1 showing 10 common numbers 17 230 2.3% 32 227 2.27% 26 225 2.25% 25 222 2.22% 3 221 2.21% 10 220 2.2% 35 218 2.18% 5 217 2.17% 13 215 2.15% 12 213 2.13% showing 10 least common numbers 40 187 1.87% 7 186 1.86% 39 185 1.85% 42 184 1.84% 43 184 1.84% 34 182 1.82% 21 175 1.75% 22 175 1.75% 18 173 1.73% 44 164 1.64%
hoover i'm getting pretty same result mt19937
, uniform_int_distribution
! what's wrong here? shouldn't uniform, or test useless?
no, should not uniform. above not evidence of error.
they random , should uniform, not exactly.
in particular expect each number occur 10000/50=200 times - standard deviation of sqrt(200) 14 - , 50 numbers expect 2 standard deviations of difference - +-/28.
the bias caused using modulus rand_max smaller that; need lot more samples detect bias.
Comments
Post a Comment