Подтвердить что ты не робот

С++ rand() дает такое же число при запуске процесса

Я новичок в С++ и задаю вопрос о rand()

каждый раз, когда я запускаю процесс с помощью rand(), он дает мне те же результаты

пример:

#include <iostream>
#include <math.h>

using namespace std;

void wait () {
    int e;
    cin >> e;
}
int random (int low, int high) {
    if (low > high) return high;
    return low + (rand() % (high - low + 1));
}
int main (int argc, char* argv []) {
    for (int i = 0; i < 5; i++) cout << random (2, 5) << endl;
    wait ();
}

вывод:

3
5
4
2
3

Каждый раз, когда я запускаю программу, он выдает одинаковые номера каждый раз. Есть ли способ обойти это?

4b9b3361

Ответ 1

Семя для генератора случайных чисел не задано.

Если вы вызываете srand (time (NULL)), вы получите более случайные результаты:

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main() {
    srand(time(NULL));
    cout << rand() << endl;
    return 0;
}

Причина в том, что случайное число, генерируемое функцией rand(), на самом деле не является случайным. Это просто трансформация. Википедия дает лучшее объяснение значения генератора псевдослучайных чисел: детерминированный генератор случайных бит. Каждый раз, когда вы вызываете rand(), он берет семя и/или последние случайные числа (с) (стандарт C не указывает используемый алгоритм, хотя С++ 11 имеет возможности для определения некоторых популярных алгоритмов), запускает математическая операция над этими числами и возвращает результат. Поэтому, если состояние семени одинаково каждый раз (так, как если бы вы не вызывали srand с действительно случайным числом), тогда вы всегда будете получать одинаковые "случайные" номера.

Если вы хотите узнать больше, вы можете прочитать следующее:

http://www.dreamincode.net/forums/topic/24225-random-number-generation-102/

http://www.dreamincode.net/forums/topic/29294-making-pseudo-random-number-generators-more-random/

Ответ 2

Если вы вызываете rand() без первого вызова srand(), он будет действовать так, как если бы вы вызывали srand(1) неявно. Соответствующий бит стандарта C99 7.20.2.2 The srand function (на котором основан cstdlib) указывает:

Если rand вызывается до того, как были сделаны какие-либо вызовы srand, такая же последовательность должна быть сгенерирована так, как когда srand сначала вызывается с начальным значением 1.

Другими словами, вы будете получать одну и ту же последовательность каждый раз. Вы можете изменить main на:

int main (int argc, char* argv []) {
    srand (time (0));  // needs ctime header.
    for (int i = 0; i < 5; i++)
        cout << random (2, 5) << endl;
    wait ();
}

чтобы исправить это, если вы не запускаете его более одного раза в секунду.

Как уже упоминалось, для этого вам понадобится заголовок ctime. Вы также должны втягивать cstdlib, так как там rand и srand вживую. Также обычно рекомендуется использовать заголовки cXXX, а не XXX.h (cmath, а не math.h, например).

Итак, сделав все эти изменения (и используя явные пространства имен, которые я предпочитаю, если другие не могут), я бы закончил с помощью:

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

void wait () {
    int e;
    std::cin >> e;
}

int random (int low, int high) {
    if (low > high) return high;
    return low + (std::rand() % (high - low + 1));
}

int main (int argc, char* argv []) {
    std::srand (std::time (0));
    for (int i = 0; i < 5; i++)
        std::cout << random (2, 5) << '\n';
    wait ();
}

который дает разную последовательность каждый раз, когда я запускаю ее, в течение нескольких раз. Очевидно, что существует жесткий предел, когда данные будут повторяться (есть только 4 5 возможности), а "случайный" характер выхода означает, что он может повториться и до этого: -)

Ответ 3

Это функция функции rand().

У вас нет генератора случайных чисел, но более строго "Генератор псевдослучайных чисел" . Возможность воспроизведения одинаковых случайных последовательностей для одного и того же семени (вы используете с помощью функции srand(x)) может быть важна для воспроизведения ошибок или сохранения состояния в программах.

Лично я использую эту функцию, чтобы иметь возможность приостанавливать/сохранять процессы рендеринга в monte carlo. Хорошим побочным эффектом является то, что вы можете гарантировать различные эксперименты с monte carlo на разных машинах и, следовательно, иметь возможность генерировать гарантированные разные результаты, которые затем могут быть уменьшены на последнем этапе до конечного результата более высокого качества (конечно, вы можете впоследствии использовать его повторно этот более качественный конечный результат для получения еще более качественных результатов).

Обратите внимание, однако, что ни C, ни С++ не определяют последовательность чисел из rand(). Поэтому, если вам нужны гарантированные последовательности на разных платформах, используйте один из генераторов случайных чисел С++ 11 (например, mersenne twister), сверните свой собственный ( однако некоторые генераторы почти тривиальны, поскольку большинство из них полагаются на специфическое поведение переполнения, реализация которых может быть не тривиальной) или использовать сторонний компонент (например, boost:: random).

Ответ 4

Вам нужно засеять генератор случайных чисел (см. функцию "srand" ). Предполагая, что вы не выполняете криптографию, то посев его с выходом "времени", вероятно, достаточно хорош.

Ответ 5

используйте randomize(). Он автоматически семениет значение. Или, если вы хотите использовать rand(), вы можете засеять его с помощью srand (seedvalue); начальное значение может быть любым, как системное время.., которое дает вам разные случайные числа каждый раз

Ответ 6

На самом деле вы получаете случайные числа psuedo. Чтобы сделать их "более случайными", вы можете засеять генератор случайных чисел, используя что-то, что "изменяется" (чаще всего текущее время).