Генерация случайного числа с определенной скоростью - PullRequest
0 голосов
/ 05 марта 2009

У меня есть следующий код C ++, который пытался сгенерировать случайное число. Идея заключается в том, что нам даны некоторая скорость "x" и количество прогонов; мы надеемся, что это сгенерирует число, равное (x * количество раз запусков).

#include <iostream>      
#include <vector>
#include <fstream>
#include <sstream>       
#include <time.h>        
using namespace std;     


int main  () {

    // Initialize Random Seed 
    srand (time(NULL));

    string line;
    double SubsRate = 0.003;  
    double nofRuns   = 1000000;

    for (unsigned i=0; i < nofRuns ; i++) {

        int toSub = rand() % 1000 + 1;

        if (toSub == (SubsRate * 1000)) {
         cout << toSub << " Sub"  << endl; 
        }

    }
    return 0;
}

Следовательно, если мы выполним код выше K раз с этой командой:

$ a=0 ; while test $a -lt 10 ; do ./MyCode | wc -l ; a=`expr $a + 1` ; done

Мы ожидаем, что он сгенерирует число "3" до ~ 3000 раз за 1M запусков. Но кое-как мой код выше моего кода выше генерирует только число «3» целых 900 ~ 1000 раз.

Как я могу улучшить мой код выше?

Ответы [ 4 ]

3 голосов
/ 05 марта 2009

Другими словами, вы проверяете, что результат == 3, а не что <= 3. </p>

3 произойдет только один раз из 1000, но <= 3 произойдет с желаемой скоростью. </p>

2 голосов
/ 05 марта 2009
  • Вы ожидаете получить номер 3 один раз из 1000, то есть 1000 раз из 1 млн.
  • Вы ожидаете получить номер 9 один раз из 1000, то есть 1000 раз из 1 млн.
  • Вы ожидаете получить номер 7 один раз из 1000, то есть 1000 раз из 1 млн.
  • Вы ожидаете получить одно из 3, 7 или 9 три раза из 1000, т.е. 3000 раз из 1 млн.
1 голос
/ 06 марта 2009

Как уже упоминали другие, ваш оригинал проверял, равно ли случайное число той части распределения, которую вы хотели, не ниже этой.

rand() генерирует значение от 0 до RAND_MAX (включительно). RAND_MAX может быть довольно маленьким - типичное значение равно 32767. Если вы используете модуль 1000, то есть 32 значения, которые rand() возвращают, которые отображаются на каждое значение от 768 до 999, и 33 значения, которые отображаются на значения от 0 до 767 Так что это немного искажено.

Вы, кажется, вытащили 1000 из воздуха. Если вместо этого вы сами масштабируете RAND_MAX на требуемую пропорцию распределения, то вы не получите эффекта перекоса, и вам не придется обрабатывать вывод rand (), чтобы выполнить сравнение:

int main  () {
    srand (time(NULL));

    double subsRate = 0.003;  

    unsigned int nofRuns   = 1000000;

    int cutoff = (int) ( subsRate * ( (long) RAND_MAX + 1L ) );

    for (unsigned int i = 0; i < nofRuns ; i++) 
        if ( rand() < cutoff ) 
            cout << " Sub "  << endl; 

    return 0;
}
1 голос
/ 05 марта 2009

Я думаю, что ваша математика здесь немного ...

В соответствии с имеющимся у вас кодом вы будете генерировать случайные числа в диапазоне от 1 до 1000.

Ваш чек (toSub == (SubsRate * 1000)) просто проверяет, является ли сгенерированное вами число 3 (с коэффициентом * 1000 = 3). Следовательно, вы получите только 3 раза, примерно 1000 раз, а не 3000 раз.

Вы не упомянули, каков диапазон ваших чисел, но, вообще говоря, если вы хотите сгенерировать число в диапазоне между IMIN и IMAX с использованием равномерного распределения (каждое значение имеет одинаковую вероятность появления), ты просто пишешь:

int I = IMin + rand() % (IMax - IMin);

В этом случае, если вы хотите, чтобы каждое число появлялось один раз каждые 3000 раз, вам придется рандомизировать число от 1 до 3000. В противном случае вы не говорите о равномерном распределении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...