C RNG (Mersenne Twister) нуждается в семенах

#c #random #distribution #seed #mersenne-twister

#c #Случайный #распределение #начальное #mersenne-twister

Вопрос:

Я написал класс RNG, который содержит разные алгоритмы, однако он работает не так, как ожидалось. Помимо того факта, что я хочу использовать нормальное (а не равномерное) распределение, мой код всегда возвращает либо одно и то же число (максимум), либо всего 2 числа из интервала [min, max]:

 std::function<int(int, int)> mt19937 =
    [](int min, int max) -> int {
        std::uniform_int_distribution<int> distribution(min, max);
        std::mt19937 engine;
        engine.seed(time(null));
        auto generator = std::bind(distribution, engine);
        return generator();
    };
  

Кто-нибудь может объяснить мне, чего не хватает для решения этой головоломки? Кроме того, как я могу реализовать нормальное распределение? В прошлый раз, когда я пробовал, std::normal_distribution я не смог ввести границы!

РЕДАКТИРОВАТЬ: когда я говорю о нормальном распределении, я имею в виду, что результаты RNG вблизи двух границ не должны генерироваться так часто, как среднее значение обоих. Например. посмотрите на графическое представление стандартного распределения Гаусса. Я имею в виду это, потому что он визуализирует вероятности результирующих значений, которые я хочу реализовать / использовать таким образом, если вы понимаете.

Комментарии:

1. Вы создаете и заполняете новый движок каждый раз, когда вам нужен новый номер? Возможно, вам следует создать движок и дистрибутив один раз, а затем запросить у них новые номера по мере необходимости.

2. Дело не в этом. Я хочу знать, почему это не работает!

3. Вероятно, поэтому он не работает.

4. Но в этом суть: если вы продолжаете пересев со временем (null), которое меняется только один раз в секунду, каждый раз, когда вам нужно случайное число, вы будете продолжать получать один и тот же ответ.

5. @Blender: Вы правы! Теперь это работает, когда я создаю движок, дистрибутив и начальное ядро раз и навсегда! (Собираюсь отредактировать мой вопрос …)

Ответ №1:

Нормальное распределение — это именно это ( x случайное равномерное число):

Нормальный

Но я вижу кое-что, что может быть проблематичным:

 std::uniform_int_distribution<int> distribution(min, max);
  

Разве это не дает вашему генератору чисел int тип?


Чтобы устранить проблему с заполнением, создайте свой движок вне лямбда-выражения и заполните его при создании.

RNG использует алгоритм, который выдает числа, которые кажутся случайными, но имеют очень большой период повторения (изюминка Mersenne Twister). Когда вы вводите начальное значение, вы присваиваете ГСЧ начальное значение для запуска процесса. Каждый раз, когда вы запрашиваете другое число, он выдает еще одну итерацию алгоритма.

Когда вы заполняете каждую итерацию:

 time(NULL)
  

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

Комментарии:

1. Правильно. Я хочу это для бросков кубиков, которые не являются однородными. Они должны быть нормальными в некоторых частях моего кода — поэтому я реализовал несколько различных типов алгоритмов.

2. Нормальное распределение — это функция распределения вероятностей . Все вероятности строго меньше единицы. Если вы используете это для игры в кости, то я предлагаю избавиться от Mersenne twister, поскольку он создан для ситуаций, когда вы запрашиваете миллиарды случайных чисел (например, движок рендеринга, где я его использую). Вы пробовали стандартный C RNG?

3. Значение по умолчанию (s)rand работает так, как ожидалось, но я хочу, чтобы значения распределялись так, как выглядит стандартный график распределения Гаусса, если вы понимаете.

4. Не обижайтесь, но проблема может быть в реализации. Вам нужно нормальное распределение, но, похоже, вы не знаете, что это такое. PDF (функция распределения вероятностей) имеет максимум 1 и интеграл от -inf до inf 1. Он описывает вероятность того x , что с ними связан определенный диапазон значений. Каким вы хотите быть в форме нормального распределения? Результаты? Вы должны быть более конкретными, поскольку то, о чем вы просите, невозможно.