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

Popular posts from this blog

php - How to add and update images or image url in Volusion using Volusion API -

Laravel mail error `Swift_TransportException in StreamBuffer.php line 269: Connection could not be established with host smtp.gmail.com [ #0]` -

C#.NET Oracle.ManagedDataAccess ConfigSchema.xsd -