Каждый тип, созданный из шаблона класса, указанного в этом разделе, [rand.eng] удовлетворяет требованиям random number engine типа.
Если не указано иное, сложность каждой функции, указанной в этом разделе, [rand.eng] является постоянной.
Если не указано иное, ни одна функция, описанная в этом разделе, не [rand.eng] вызывает исключение.
Каждая функция, описанная в этом разделе, [rand.eng] которая имеет параметр функции q типа Sseq& для параметра типа шаблона с именем Sseq , отличным от типа, seed_seq вызывает то, что и когда q.generate вызывает вызов throw.
Описания представлены в этом разделе [rand.eng] только для операций двигателя, которые не описаны, [rand.req.eng] или для операций, для которых имеется дополнительная семантическая информация. В частности, объявления для конструкторов копирования, для операторов присваивания копий, для операторов потоковой передачи и для операторов равенства и неравенства не показаны в резюме.
Каждый шаблон, указанный в этом разделе, [rand.eng] требует удержания одного или нескольких отношений, включающих значение (значения) не относящихся к типу параметров шаблона. Программа, реализующая любой из этих шаблонов, плохо сформирована, если какая-либо такая требуемая взаимосвязь не выполняется.
Для каждого механизма случайных чисел и для каждого адаптера механизма случайных чисел, X определенных в этом подпункте ([rand.eng]) и в подпункте [rand.adapt]:
если конструктор
template <class Sseq> explicit X(Sseq& q);
вызывается с типом Sseq , который не квалифицируется как начальная последовательность, тогда этот конструктор не должен участвовать в разрешении перегрузки;
если функция-член
template <class Sseq> void seed(Sseq& q);
вызывается с типом Sseq , который не квалифицируется как начальная последовательность, то эта функция не должна участвовать в разрешении перегрузки.
Степень, в которой реализация определяет, что тип не может быть начальной последовательностью, не указана, за исключением того, что, как минимум, тип не должен квалифицироваться как начальная последовательность, если он неявно конвертируется в X::result_type.
Механизм linear_congruential_engine случайных чисел производит беззнаковые целые случайные числа. Состояние из объекта имеет размер и состоит из одного целого числа. Алгоритм перехода представляет собой модульную линейную функцию формы ; алгоритм генерации есть . xi linear_congruential_engine x 1TA(xi)=(a⋅xi+c)modm GA(xi)=xi+1
template<class UIntType, UIntType a, UIntType c, UIntType m> class linear_congruential_engine { public: // types using result_type = UIntType; // engine characteristics static constexpr result_type multiplier = a; static constexpr result_type increment = c; static constexpr result_type modulus = m; static constexpr result_type min() { return c == 0u ? 1u: 0u; } static constexpr result_type max() { return m - 1u; } static constexpr result_type default_seed = 1u; // constructors and seeding functions explicit linear_congruential_engine(result_type s = default_seed); template<class Sseq> explicit linear_congruential_engine(Sseq& q); void seed(result_type s = default_seed); template<class Sseq> void seed(Sseq& q); // generating functions result_type operator()(); void discard(unsigned long long z); };
Если параметр шаблона m равен 0, модуль, m используемый в этом разделе, равен плюсу . [ не обязательно представлять как значение типа . ] [rand.eng.lcong] numeric_limits<result_type>::max() 1 Note: m result_type — end note
explicit linear_congruential_engine(result_type s = default_seed);
Effects: Создает linear_congruential_engine объект. Если cmodm есть 0 и smodm есть 0, устанавливает состояние двигателя в 1, в противном случае устанавливает состояние двигателя в smodm.
template<class Sseq> explicit linear_congruential_engine(Sseq& q);
Effects: Создает linear_congruential_engine объект. С k=⌈log2m32⌉ и a массивом (или эквивалентом) длины k+3вызывает, q.generate(a+0, a+k+3) а затем вычисляет S=(∑k−1j=0aj+3⋅232j)modm. Если cmodm есть 0 и S есть 0, устанавливает состояние двигателя в 1, иначе устанавливает состояние двигателя в S.
Механизм mersenne_twister_engine случайных чисел270 производит беззнаковые целые случайные числа в закрытом интервале [0,2w−1]. Состояние из объекта имеет размер и состоит из последовательности из значений типа поставляемого ; все применяемые индексы следует брать по модулю .xi mersenne_twister_engine x n X n x X n
Алгоритм перехода использует сдвиговый регистр с обобщенной обратной связью, определяемый значениями сдвига и , значением поворота и условной xor-маской . Чтобы улучшить однородность результата, биты необработанного регистра сдвига дополнительно (т. Е. Скремблируются) в соответствии с матрицей битового скремблирования, определенной значениями и . n m r a tempered u,d,s,b,t,c, ℓ
Переход между состояниями выполняется следующим образом:
a)Соедините верхние w−r биты Xi−n с младшими r битами, Xi+1−n чтобы получить беззнаковое целое число Y.
b)С α=a⋅(Ybitand1), установите Xi на Xi+m−nxor(Yrshift1)xorα.
Последовательность X инициализируется с помощью множителя инициализации f.
Алгоритм генерации определяет беззнаковые целочисленные значения следующим образом, а затем выдает в качестве своего результата: z1,z2,z3,z4 z4
a)Пусть z1=Xixor((Xirshiftu)bitandd).
b)Пусть z2=z1xor((z1lshiftws)bitandb).
c)Пусть z3=z2xor((z2lshiftwt)bitandc).
d)Пусть z4=z3xor(z3rshiftℓ).
template<class UIntType, size_t w, size_t n, size_t m, size_t r, UIntType a, size_t u, UIntType d, size_t s, UIntType b, size_t t, UIntType c, size_t l, UIntType f> class mersenne_twister_engine { public: // types using result_type = UIntType; // engine characteristics static constexpr size_t word_size = w; static constexpr size_t state_size = n; static constexpr size_t shift_size = m; static constexpr size_t mask_bits = r; static constexpr UIntType xor_mask = a; static constexpr size_t tempering_u = u; static constexpr UIntType tempering_d = d; static constexpr size_t tempering_s = s; static constexpr UIntType tempering_b = b; static constexpr size_t tempering_t = t; static constexpr UIntType tempering_c = c; static constexpr size_t tempering_l = l; static constexpr UIntType initialization_multiplier = f; static constexpr result_type min() { return 0; } static constexpr result_type max() { return 2w−1; } static constexpr result_type default_seed = 5489u; // constructors and seeding functions explicit mersenne_twister_engine(result_type value = default_seed); template<class Sseq> explicit mersenne_twister_engine(Sseq& q); void seed(result_type value = default_seed); template<class Sseq> void seed(Sseq& q); // generating functions result_type operator()(); void discard(unsigned long long z); };
Следующие соотношения должны занимать: 0 < m, m <= n, 2u < w, r <= w, u <= w, s <= w, t <= w, l <= w, w <= numeric_limits<UIntType>::digits, a <= (1u<<w) - 1u, b <= (1u<<w) - 1u, c <= (1u<<w) - 1u, d <= (1u<<w) - 1u, и f <= (1u<<w) - 1u.
explicit mersenne_twister_engine(result_type value = default_seed);
Effects: Создает mersenne_twister_engine объект. Устанавливается X−n на valuemod2w. Затем итеративно для i=1−n,…,−1, наборы Xi для
[f⋅(Xi−1xor(Xi−1rshift(w−2)))+imodn]mod2w.
template<class Sseq> explicit mersenne_twister_engine(Sseq& q);
Effects: Создает mersenne_twister_engine объект. With k=⌈w/32⌉ и a массив (или эквивалент) длины n⋅kвызывает, q.generate(a+0, a+n⋅k) а затем, итеративно для i=−n,…,−1, устанавливает Xi значение (∑k−1j=0ak(i+n)+j⋅232j)mod2w. Наконец, если наиболее значимые w−r биты X−n равны нуль, и если каждый из других в результате чего Xi это 0, изменяется X−n с 2w−1.
Название этого механизма частично относится к свойству его периода: для правильно выбранных значений параметров период тесно связан с большим простым числом Мерсенна.
Механизм subtract_with_carry_engine случайных чисел производит беззнаковые целые случайные числа.
Состояние из объекта имеет размера , и состоит из последовательности из целочисленных значений ; все применяемые индексы следует брать по модулю . Состояние дополнительно состоит из целого числа (известного как ) , значение которого равно или . xi subtract_with_carry_engine xO(r) X r 0≤Xi<m=2w X r xi c carry 0 1
Переход между состояниями выполняется следующим образом:
a)Пусть Y=Xi−s−Xi−r−c.
b)Установите Xi на y=Ymodm. Установите c в 1, если Y<0, в противном случае установите c в 0.
[ Note: Этот алгоритм соответствует модульной линейной функции вида TA(xi)=(a⋅xi)modb, где b имеет вид mr−ms+1 и a=b−(b−1)/m. ] — end note
Алгоритм генерации задается формулой , где - значение, полученное в результате улучшения состояния двигателя, как описано выше.GA(xi)=y y
template<class UIntType, size_t w, size_t s, size_t r> class subtract_with_carry_engine { public: // types using result_type = UIntType; // engine characteristics static constexpr size_t word_size = w; static constexpr size_t short_lag = s; static constexpr size_t long_lag = r; static constexpr result_type min() { return 0; } static constexpr result_type max() { return m−1; } static constexpr result_type default_seed = 19780503u; // constructors and seeding functions explicit subtract_with_carry_engine(result_type value = default_seed); template<class Sseq> explicit subtract_with_carry_engine(Sseq& q); void seed(result_type value = default_seed); template<class Sseq> void seed(Sseq& q); // generating functions result_type operator()(); void discard(unsigned long long z); };
Следующие соотношения должны проводить: 0u < s, s < r, 0 < w, и w <= numeric_limits<UIntType>::digits.
Текстовое представление состоит из значений в указанном порядке, за которыми следует . Xi−r,…,Xi−1 c
explicit subtract_with_carry_engine(result_type value = default_seed);
Effects: Создает subtract_with_carry_engine объект. Устанавливает значения X−r,…,X−1в указанном ниже порядке в указанном ниже порядке. Если X−1 есть, то 0устанавливается c в 1; в противном случае устанавливается c на 0.
Для того, чтобы установить значение Xk, первые построить e, А linear_congruential_engine объект, как если бы по следующему определению:
linear_congruential_engine<result_type, 40014u,0u,2147483563u> e(value == 0u ? default_seed : value);
Затем, чтобы установить каждый Xk, получить новые значения z0,…,zn−1 из n=⌈w/32⌉ последовательных вызовов e взятого по модулю 232. Установите Xk на (∑n−1j=0zj⋅232j)modm.
template<class Sseq> explicit subtract_with_carry_engine(Sseq& q);
Effects: Создает subtract_with_carry_engine объект. With k=⌈w/32⌉ и a массив (или эквивалент) длины r⋅kвызывает, q.generate(a+0, a+r⋅k) а затем, итеративно для i=−r,…,−1, устанавливает Xi значение (∑k−1j=0ak(i+r)+j⋅232j)modm. Если X−1 есть, то 0устанавливается c в 1; в противном случае устанавливается c на 0.