Создать случайное целое число в диапазоне от случайного двойного

Я получаю случайное двойное число [0,1) от твистера Мерсенна. Как я могу получить случайный [0, x) из вывода вихря Мерсенна?

Твистер Мерсенна выводит либо случайное целое число в общем диапазоне, либо случайное [0,1)

Важно, чтобы он был равномерно распределен, поэтому я сомневаюсь, что базовый floor(mersenneRandom()*x) подойдет.

если получится, то отлично.


person Tree    schedule 19.01.2015    source источник
comment
Почему реализация твистера Мерсенна, которую вы используете, дает двойника? Базовый алгоритм предоставляет случайные биты, которые легче всего собрать в целые значения, производя случайные значения, равномерно распределенные по диапазону целочисленного типа. Если вы получаете удвоение, то что-то в API принимает эти целочисленные значения и выполняет преобразование в удвоение.   -  person bames53    schedule 19.01.2015
comment
Плюс один за то, что спросил. Существует слишком много кода, который злоупотребляет генераторами случайных чисел,   -  person Bathsheba    schedule 19.01.2015
comment
math.sci.hiroshima-u.ac. jp/~m-mat/MT/SFMT   -  person Tree    schedule 19.01.2015


Ответы (1)


Еще один случай для вашего любимого справочника!

#include <random>
#include <iostream>



int main()
{
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<> dis(1, 2);
    for (int n = 0; n < 10; ++n) {
        std::cout << dis(gen) << ' ';
    }
    std::cout << '\n';
}

(взято из здесь) генерирует значения в [1,2), и сайт объясняет, как это сделать для произвольного [a,b)!

Если вам нужны целые числа, используйте std::uniform_int_distribution.

floor(mersenneRandom()*x) действительно не работает, потому что разница между double-значением и следующим большим значением становится больше единицы для больших чисел. Вы бы пропустили все целые числа между этими двумя значениями.

person Baum mit Augen    schedule 19.01.2015
comment
поэтому mathFloor выровняется для небольших чисел на 100 000 000 запросов, возвращающих неравномерно распределенные числа, хотя ГСЧ работал правильно - person Tree; 19.01.2015
comment
@Tree Я полагаю, что это должно подойти для небольших чисел, но проблемы с ГСЧ часто бывают очень тонкими, я могу что-то упустить. Вы на самом деле не должны пытаться создавать подобные вещи вручную и использовать реализации людей, которые потратили больше времени на исследование RNG, таких как упомянутые выше или boost::random, если вы не можете использовать C++11. Как вы, возможно, заметили ранее, даже Bathseba, хороший и опытный программист, облажался с первой попытки (просто чтобы показать вам, как трудно сделать это правильно). - person Baum mit Augen; 19.01.2015
comment
Я использовал форму примера st::uniform_int_distribution, но мне все еще интересно, является ли это лучшим решением, потому что оно включает двойное значение в расчет равномерного распределения. Я все еще ищу конечное решение, в котором вы получаете random(x), который возвращает [0,x), но не нашел его. На данный момент это решение дает наилучшие результаты при равномерном распределении - person Tree; 20.01.2015
comment
@Tree std::uniform_int_distribution не имеет ничего общего с doubles, оно просто сопоставляет случайные биты std::mt19337 (скручивание Мерсенна) как можно более равномерно с предоставленным вами целочисленным диапазоном. - person Baum mit Augen; 21.01.2015