2013-12-21 6 views
2

C++ вопрос здесь, используя Code :: Blocks. Я пытаюсь запустить этот код, чтобы проверить псевдослучайной функциюRand() возвращает одинаковые или очень похожие выходные значения

#include <iostream> 
#include <cstdlib> 
#include <ctime> 

using namespace std; 

int main() 
{ 
    int count = 0; 
    while (count < 10){ 
     srand(time(NULL)); 
     cout << rand() << ' '; 
     cout << (time(NULL)) << " \n"; 
     count++; 
    } 
    return 0; 
} 

Выход из этого 10 равных линий. Это не проблема, так как семя здесь одно и то же, поэтому результат должен быть таким же. Проблема в том, что если я снова запустил эту программу, она даст 10 очень похожих строк с небольшим изменением не только на выходе time(), но и на выходе rand.

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

(Возврат 9631 при первом запуске, а затем 9656 на второй).

Мой вопрос в том, что ожидаемое поведение? И как я могу получить более разные результаты, например, 38 при первом запуске, а 671 - во втором?

+0

Не могли бы вы быть более точными. Что вы ожидаете увидеть? Что ты видишь? Как это не оправдает ваши ожидания? –

ответ

0

Чтобы сделать случайное число с почти одним и тем же семенем (время), вы можете добавить статическую переменную, чтобы rand() вел себя иначе, даже с тем же параметром; или, вы можете изменить параметр, когда получите такое же время. Например:

int t=0; 
... 
rand(t=(t*7)^time(NULL)); 
+0

Это действительно отличное решение! Я сделал это, и я мог бы получить 100 различных решений, используя одно и то же время (запустив эту программу один раз, при этом счетчик будет равен 100). Повторяя это снова, похоже, что предсказуемость решений также очень, очень и очень низкая. Единственное, что я должен добавить, это то, что вызов функции, который мне нужно изменить, был srand, а не rand. Но я понял, что вы имели в виду. Большое спасибо! –

2

Множество неправильных представлений здесь ... То, что разница между двумя звонками, близкими друг другу, является небольшой, как ожидается. В конце концов, время движется только так быстро. Следующая проблема заключается в том, что rand() возвращает (псевдо) случайное значение (различного качества): Случайное в этом случае означает, что вы можете получить 33 несколько раз, если это не предсказуемо. При этом rand() зависит от реализации, и вполне может быть, что ваша реализация использует нечто вроде LCG, который не генерирует хорошие равномерные случайные значения. Единственное исправление для этого - переход на другой rng. Поскольку это помечено как C++, вы можете захотеть взглянуть на случайный заголовок C++ 11s и использовать что-то вроде своей реализации mersenne twister, которая является хорошим генератором псевдослучайных чисел, который производит случайные числа с отличным качеством и равномерным распределением.

+0

Я знаю все это. Все, о чем я говорю, это то, что, как только я узнаю значение, которое получаю в первый раз, когда я запускал свою программу, я могу ожидать, какое значение я получу, если я закрою его и запустил снова. Я могу даже потратить время на то, как долго это число достигнет определенной точки, и тогда я всегда могу предсказать число, которое я получу от него. Это не дает мне ничего случайного. Даже не что-то псевдослучайное. Если бы я только что напечатал «Time (null)», результат был бы пиратски одинаковым: всегда увеличивающееся число, которое растет с определенной скоростью. –

1

Разница между различными вариантами выполнения, по-видимому, будет небольшой разницей в изменении в time. Результаты rand могут быть различными для различных сред выполнения C, но вот реализация rand из Visual Studio 10.

int __cdecl rand() 
{ 
    _ptiddata ptd = _getptd(); 

    return(((ptd->_holdrand = ptd->_holdrand * 214013L 
     + 2531011L) >> 16) & 0x7fff); 
} 

holdrand Где хранит семена, чтобы начать запуск с. Это linear congruential generator, которые обычно не производят высококачественную случайность. Это также отбрасывает много состояний каждый раз, что не помогает.

+0

Итак, в основном, это означает, что работа на ранде, по сути, является линейной и предсказуемой функцией? Ну, тогда я думаю, что единственный способ заставить его казаться, будто он возвращает случайное значение, - если я ограничу максимальное значение, которое я могу получить от него. Подобно использованию rand (time (0))% 10 или% однозначного числа. Чем больше результат, тем я стараюсь получить более похожие и предсказуемые результаты. –