Так, я пытаюсь создать случайный вектор (думайте геометрия, не расширяемый массив), и каждый раз, когда я называю свою случайную вектор-функцию, я получаю то же значение 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? Я - отбор неправильно?
Проблема в том, что генератор случайных чисел заполняется значениями, которые очень близки друг к другу - каждый запуск программы изменяет возвращаемое значение time () только на небольшую величину - возможно 1 секунда, а может, и никакой! Затем довольно плохой стандартный генератор случайных чисел использует эти похожие начальные значения для генерации явно идентичных начальных случайных чисел. По сути, вам нужен лучший генератор начальных семян, чем time (), и лучший генератор случайных чисел, чем rand ().
Фактический используемый алгоритм цикла, я думаю, заимствован из Accelerated C ++ и предназначен для получения лучшего распределения чисел в требуемом диапазоне, чем, скажем, при использовании оператора mod. Но он не может компенсировать постоянное (эффективное) получение одного и того же семени.
Я не вижу никаких проблем с вашим srand ()
, и когда я попытался запустить очень похожий код, я не получал того же номер с первым rand ()
. Однако я заметил еще одну возможную проблему.
do randx = (rand()/bucket_size)+min;
while (randx <= min && randx >= max);
Эта строка, вероятно, не соответствует вашим намерениям. Пока min
randx
не может быть одновременно меньше или равно min
и больше или равно до макс.
. Кроме того, вам вообще не нужно зацикливаться. Вместо этого вы можете получить значение между min и max, используя:
randx = rand() % (max - min) + min;
Также следует упомянуть, что вы даже можете избавиться от этой странной переменной 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;
Ваша реализация посредством целочисленного деления игнорирует наименьшие 4-5 битов случайного числа. Поскольку ваш ГСЧ заполнен системным временем, первое полученное вами значение будет изменяться только (в среднем) каждые 20 секунд.
Это должно сработать:
randx = (min) + (int) ((max - min) * rand() / (RAND_MAX + 1.0));
где
rand() / (RAND_MAX + 1.0)
- случайное двойное значение в [0, 1), а остальное просто меняет его.
Простое быстрое исправление - вызвать 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
Это выглядит намного лучше, не так ли? Я действительно не вижу причин для отрицательных голосов.