Есть ли способ передать несколько чисел (в моем случае 3) в качестве начальных чисел для случайной работы? Мне нужно, чтобы результат был псевдослучайным значением с линейным распределением, поэтому я не могу просто использовать что-то в качестве srand(x + y + z);
, потому что srand((x+n) + y + z);
даст тот же результат, что и srand(x + (y+n) + z);
, что предсказуемо.
В качестве альтернативы std::random_device
поддерживает именованные «токены», которые позволяют извлекать случайные значения либо из ОС (/dev/random
), либо из ЦП (rdrand
).
Напоминаем, что функции srand() и rand() сохраняются в библиотеке C++ только в целях обратной совместимости, то есть для обеспечения плавной перекомпиляции древнего исходного кода. Они предоставляют очень мало статистических гарантий. Новый код C++ должен использовать возможности, предоставляемые заголовочным файлом <random> C++11. Полную информацию можно найти в Генерация случайных чисел C++11 N3551.
Вам стоит посмотреть rand() считается вредным.
Кажется, это задача для класса std::seed_seq в рамках C++11 PRNG.
Объект этого класса инициализируется несколькими входными целочисленными значениями в ваших обозначениях x,y,z и может распределять свою «энтропию» на произвольное количество выходных целочисленных значений, обычно такое же большое, как состояние вашего объекта. псевдослучайный генератор. Алгоритм расширения намного сложнее, чем простое сложение входных значений.
Используя популярный движок Mersenne Twister, мы можем подготовить два генератора, которые отличаются только перестановкой y и z:
#include <string>
#include <iostream>
#include <random>
#include <algorithm>
int main()
{
std::seed_seq seed1{314159, 26535, 897932};
std::seed_seq seed2{314159, 897932, 26535};
std::mt19937 gen1 (seed1);
std::mt19937 gen2 (seed2);
Мы можем использовать эти два генератора, например, для случайных перестановок латинского алфавита:
std::string str0{"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
std::string str1{str0};
std::string str2{str0};
std::shuffle(str1.begin(), str1.end(), gen1);
std::shuffle(str2.begin(), str2.end(), gen2);
std::cout << "With gen1: " << str1 << '\n';
std::cout << "With gen2: " << str2 << '\n';
return EXIT_SUCCESS;
}
Вывод тестовой программы:
With gen1: XIUKCMQELBARJTNOYFDSPVHGWZ
With gen2: CRIXQYKHEPUSGJZNVAMWOTLDBF
Таким образом, мы получаем 2 разные перестановки, доказывая тем самым, что наши 2 генератора стартовали из разных состояний. Алгоритм расширения, безусловно, более сложен, чем простое коммутативное сложение.
См. также обсуждение здесь: SO-q22522829
Тогда не используйте простое сложение для генерации случайных чисел. Вместо этого используйте хеш-функцию, которая дает радикально разные результаты в зависимости от порядка входных данных. И, конечно же, вместо этого используйте «новую» (читай: C++11, которому уже 13 лет)
<random>
инфраструктуру.