Множественные начальные числа для случайного C++

Есть ли способ передать несколько чисел (в моем случае 3) в качестве начальных чисел для случайной работы? Мне нужно, чтобы результат был псевдослучайным значением с линейным распределением, поэтому я не могу просто использовать что-то в качестве srand(x + y + z);, потому что srand((x+n) + y + z); даст тот же результат, что и srand(x + (y+n) + z);, что предсказуемо.

Тогда не используйте простое сложение для генерации случайных чисел. Вместо этого используйте хеш-функцию, которая дает радикально разные результаты в зависимости от порядка входных данных. И, конечно же, вместо этого используйте «новую» (читай: C++11, которому уже 13 лет) <random> инфраструктуру.

Botje 16.04.2024 09:39

В качестве альтернативы std::random_device поддерживает именованные «токены», которые позволяют извлекать случайные значения либо из ОС (/dev/random), либо из ЦП (rdrand).

Botje 16.04.2024 09:45

Напоминаем, что функции srand() и rand() сохраняются в библиотеке C++ только в целях обратной совместимости, то есть для обеспечения плавной перекомпиляции древнего исходного кода. Они предоставляют очень мало статистических гарантий. Новый код C++ должен использовать возможности, предоставляемые заголовочным файлом <random> C++11. Полную информацию можно найти в Генерация случайных чисел C++11 N3551.

jpmarinier 16.04.2024 16:33

Вам стоит посмотреть rand() считается вредным.

Jesper Juhl 17.04.2024 20:54
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
4
131
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кажется, это задача для класса 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

Другие вопросы по теме