рэнд () генерация того же числа – даже с srand (время (ПУСТОЙ УКАЗАТЕЛЬ)) в моем основном!

Так, я пытаюсь создать случайный вектор (думайте геометрия, не расширяемый массив), и каждый раз, когда я называю свою случайную вектор-функцию, я получаю то же значение x, хотя y и z отличаются.

int main () {
    srand ( (unsigned)time(NULL));
    Vector<double> a;
    a.randvec();
    cout << a << endl;
    return 0;
}

использование функции

//random Vector
template <class T>
void Vector<T>::randvec()
{
    const int min=-10, max=10;
    int randx, randy, randz;

    const int bucket_size = RAND_MAX/(max-min);

    do randx = (rand()/bucket_size)+min;
    while (randx <= min && randx >= max);
    x = randx;

    do randy = (rand()/bucket_size)+min;
    while (randy <= min && randy >= max);
    y = randy;

    do randz = (rand()/bucket_size)+min;
    while (randz <= min && randz >= max);
    z = randz;
}

По некоторым причинам randx будет последовательно возвращаться 8, тогда как другие числа, кажется, следуют за (псевдо) случайностью отлично. Однако, если я поместил вызов для определения, скажем, похотливый, прежде чем randx, похотливый будет всегда возвращаться 8.

Почему всегда мое первое случайное число 8? Я - отбор неправильно?

14
задан Jonathan Leffler 13 June 2010 в 15:44
поделиться

5 ответов

Проблема в том, что генератор случайных чисел заполняется значениями, которые очень близки друг к другу - каждый запуск программы изменяет возвращаемое значение time () только на небольшую величину - возможно 1 секунда, а может, и никакой! Затем довольно плохой стандартный генератор случайных чисел использует эти похожие начальные значения для генерации явно идентичных начальных случайных чисел. По сути, вам нужен лучший генератор начальных семян, чем time (), и лучший генератор случайных чисел, чем rand ().

Фактический используемый алгоритм цикла, я думаю, заимствован из Accelerated C ++ и предназначен для получения лучшего распределения чисел в требуемом диапазоне, чем, скажем, при использовании оператора mod. Но он не может компенсировать постоянное (эффективное) получение одного и того же семени.

8
ответ дан 1 December 2019 в 13:21
поделиться

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

do randx = (rand()/bucket_size)+min;
while (randx <= min && randx >= max);

Эта строка, вероятно, не соответствует вашим намерениям. Пока min (а так должно быть всегда), randx не может быть одновременно меньше или равно min и больше или равно до макс. . Кроме того, вам вообще не нужно зацикливаться. Вместо этого вы можете получить значение между min и max, используя:

randx = rand() % (max - min) + min;
5
ответ дан 1 December 2019 в 13:21
поделиться

Также следует упомянуть, что вы даже можете избавиться от этой странной переменной bucket_size и использовать следующий метод для генерации чисел от a до b включительно:

srand ((unsigned)time(NULL));

const int a = -1;
const int b = 1;

int x = rand() % ((b - a) + 1) + a;
int y = rand() % ((b - a) + 1) + a;
int z = rand() % ((b - a) + 1) + a;
3
ответ дан 1 December 2019 в 13:21
поделиться

Ваша реализация посредством целочисленного деления игнорирует наименьшие 4-5 битов случайного числа. Поскольку ваш ГСЧ заполнен системным временем, первое полученное вами значение будет изменяться только (в среднем) каждые 20 секунд.

Это должно сработать:

randx = (min) + (int) ((max - min) * rand() / (RAND_MAX + 1.0));

где

rand() / (RAND_MAX + 1.0)

- случайное двойное значение в [0, 1), а остальное просто меняет его.

0
ответ дан 1 December 2019 в 13:21
поделиться

Простое быстрое исправление - вызвать rand несколько раз после заполнения.

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

    Vector<double> a;
    a.randvec();
    cout << a << endl;
    return 0;
}

Чтобы лучше объяснить, первый вызов rand () в четырех последовательных запусках тестовой программы дал следующий результат:

27592
27595
27598
27602

Обратите внимание, насколько они похожи? Например, если вы разделите rand () на 100, вы получите одно и то же число 3 раза подряд. Теперь посмотрим на второй результат функции rand () за четыре последовательных запуска:

11520
22268
248
10997

Это выглядит намного лучше, не так ли? Я действительно не вижу причин для отрицательных голосов.

2
ответ дан 1 December 2019 в 13:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: