Почему генерируемые случайные числа отличаются, хотя начальное значение одно и то же?

#c

#c

Вопрос:

Случайные числа генерируются в один и тот же момент, т.е. в одно и то же время.Следовательно, начальное значение должно быть одинаковым и совпадает.Но почему генерируемые случайные числа отличаются, хотя условия одинаковы.

 # include < cstdlib > 
# include < iostream > 
#include < ctime >
using namespace std;
int main()
        {
        double a,b;

    srand(time(0));
    a = rand()% (1000   1 - 200)   200;   
    cout << "Seed = " << time(0) << endl;
    cout<<a<<endl;
    b = rand()% (1000   1 - 200)   200;  
    cout << "Seed = " << time(0) << endl;
    cout<<b<<endl;
    return 0;
}
  

Ожидаемый
Первое число =
529
Второе число =
529

Фактические результаты Первое число = 529 Второе число = 819

Ответ №1:

PRNGS генерируют последовательность чисел, сохраняя состояние. Это в сочетании с алгоритмом, используемым PRNG, полностью определяет число, которое выдаст вызов. Таким образом, состояние также должно изменяться при вызове PRNG, иначе оно будет выдавать точно такое же число при каждом вызове.

Вы вводите один раз, а затем вызываете PRNG. Это изменяет его внутреннее состояние и возвращает число. Следующий вызов не будет работать в том же состоянии, поэтому он может выдать другое число. И это происходит в вашем примере

Начальное значение — это то, как вы определяете состояние, с которого запускается PRNG. Если бы вы добавили еще один вызов в srand(time(0)) перед повторным вызовом rand , он с большой вероятностью может вернуть предыдущий номер, потому что, как вы правильно заметили, у time , возможно, не было возможности обновить. Вот почему общим советом является заполнение только один раз для каждой программы таким образом.

Ответ №2:

Генераторы псевдослучайных чисел действительно генерируют последовательность псевдослучайных чисел. В какой-то момент последовательность повторится (после очень долгого времени для хорошего prng). С помощью начального значения вы просто выбираете, с чего начать последовательность. Следовательно, для одного и того же начального значения вы всегда будете получать одну и ту же последовательность, но обычно вы не получите последовательность из всех одинаковых чисел. Вызов rand всегда приведет вас к следующему номеру в последовательности.

Ответ №3:

Ваше начальное значение всегда отличается, поскольку вы вызываете srand с time(0) помощью. Даже если вы передаете 0 , оно все равно возвращает время, которое всегда будет разным для разных вызовов.

Вы можете увидеть это из документации для time

time_t time (time_t* timer);

Получить текущее время Получить текущее календарное время в качестве значения типа time_t .

Функция возвращает это значение, и если аргумент не является нулевым указателем, она также присваивает это значение объекту, на который указывает timer.

Если вы хотите, чтобы ваше начальное значение было одинаковым, просто сделайте его константой.

Ответ №4:

Здесь вы вводите RNG:

 srand(time(0));
  

Тогда вы получаете случайное число из него здесь:

 a = rand()% (1000   1 - 200)   200; 
  

И еще одно случайное число здесь:

 b = rand()% (1000   1 - 200)   200;  
  

Ничто другое не влияет на результат, который вы получаете. Печать time(0) не изменит результат. Однако вы могли бы поставить другое srand(time(0)); перед b = rand()% , тогда вы, скорее всего, получите один и тот же результат дважды (при условии, что время в обоих случаях было одинаковым, но вы увидите это при печати времени).

Ответ №5:

Почему генерируемые случайные числа отличаются, хотя начальное значение одно и то же.

Ваше утверждение неверно… начальное значение, которое ваш код предоставляет srand, отличается для каждой секунды.


В C целочисленный литерал 0 (при использовании в качестве фактического параметра функции с параметром указателя) обрабатывается так же, как nullptr . Это требование C для переносимости вашего кода на те (необычные) компьютеры, где значение nullptr не равно 0x0.

Объявление

 std::time_t time( std::time_t* arg );
  

показывает, что arg является указателем на структуру.

При вызове

 std::time_t time(0);
  

язык C изменит 0 на значение nullptr, подходящее для вашего оборудования.

Таким образом, time (nullptr) каждую секунду возвращает другой результат. (Но тот же результат при быстром вызове более одного раза за заданную секунду настенных часов.)

Таким образом

 srand(time(0));
  

для каждой секунды настенных часов будет выдаваться разное начальное значение последовательности.