Как и предполагает название, я пытаюсь выяснить способ генерации случайных чисел с использованием нового C++11 в <случайных>
библиотека. Я пробовал с этим кодом:
std::default_random_engine generator;
std::uniform_real_distribution<double> uniform_distance(1, 10.001);
Проблема с кодом у меня заключается в том, что каждый раз, когда я скомпилировать и запустить его, он всегда генерирует одинаковые числа. Так что мой вопрос, какие другие функции в случайной библиотека может сделать это, будучи действительно случайные?
Для моего конкретного случая использования, я пытался получить значение в пределах диапазона [1, 10]
Т. Lavavej Стефан (стл) от Microsoft не говорить на родных о том, как использовать новый C++11 случайных функций и почему бы не использовать функции RAND()`. В нем он включен слайд, который в основном решает ваш вопрос. Я'вэ скопировал код из этого слайд ниже.
Здесь вы можете увидеть полный разговор: http://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful
#include <random>
#include <iostream>
int main() {
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_real_distribution<double> dist(1.0, 10.0);
for (int i=0; i<16; ++i)
std::cout << dist(mt) << "\n";
}
Мы используем выполнения random_deviceодин раз, чтобы семя генератора случайных чисел под названием
Т.
выполнения random_device()медленнее
mt19937, но для этого не нужно быть заполнена, потому что он просит случайные данные от вашей операционной системы (которая будет источником различных местах, как RdRand например).
Глядя на вопрос / ответ, представляется, что uniform_real_distribution
возвращает число в диапазоне [А, B)
, где [А, B]
. Для этого наши uniform_real_distibution должны на самом деле выглядеть так:
std::uniform_real_distribution<double> dist(1, std::nextafter(10, DBL_MAX));
Мой 'случайных' библиотека обеспечивают высокий удобный враппер на C++11 случайных классов. Вы можете делать почти все с простого 'вам' метод.
Примеры:
авто Валь = случайный::получить(-10, 10); // целое число авто Вэл = случайный::сделать(10.Ф -10.Ф); // плавающей точкой
авто Валь = случайный::получить в<типа bool и GT;( ) // 50% для создания истинного авто Валь = случайный::получить в<типа bool и GT;( 0.7 ) // 70%, чтобы создать настоящий
авто Валь = случайный::вам( { 1, 3, 5, 7, 9 } ); // Валь = 1 или 3 или...
авто это = случайный::получить( ВМК.начать(), ВМК.конец() ); // это = произвольный итератор авто это = случайный::получить( ВМК ); // возвращает итератор произвольного
И еще больше вещей ! Проверьте страницу GitHub:
Здесь's что-то, что я написал в этом духе::
#include <random>
#include <chrono>
#include <thread>
using namespace std;
//==============================================================
// RANDOM BACKOFF TIME
//==============================================================
class backoff_time_t {
public:
random_device rd;
mt19937 mt;
uniform_real_distribution<double> dist;
backoff_time_t() : rd{}, mt{rd()}, dist{0.5, 1.5} {}
double rand() {
return dist(mt);
}
};
thread_local backoff_time_t backoff_time;
int main(int argc, char** argv) {
double x1 = backoff_time.rand();
double x2 = backoff_time.rand();
double x3 = backoff_time.rand();
double x4 = backoff_time.rand();
return 0;
}
~
Здесь какая-ресурсе вы можете узнать о псевдо-генератор случайных чисел.
https://en.wikipedia.org/wiki/Pseudorandom_number_generator
В основном, случайные числа в компьютере нужен семени (это число может быть текущее системное время).
Заменить
std::default_random_engine generator;
По
std::default_random_engine generator(<some seed number>);
Вы've получили две типичные ситуации. Первый заключается в том, что вы хотите случайных чисел и разве'т слишком беспокоились за качество и скорость исполнения. В этом случае используйте следующий макрос
#define uniform() (rand()/(RAND_MAX + 1.0))
что дает вам P в диапазоне от 0 до 1 - Эпсилон (если RAND_MAX больше, чем точность, но не беспокоиться о том, что когда вы приходите к ней).
инт х = (тип int) (единые() * Н);
Теперь выдает случайное целое число от 0 до n -1.
Если вам нужны другие дистрибутивы, вы должны превратить стр. Или иногда это'ы легче назвать равномерным() несколько раз.
Если вы хотите, повторяющееся поведение, семя с постоянным, иначе семена с вызовом времени().
Теперь, если вы беспокоитесь о качестве или запустить сроков выполнения работ, переписать форму(). А в остальном Дон'т прикоснуться к код. Всегда держать равномерную() от 0 до 1 минус Эпсилон. Теперь вы можете обернуть библиотеки C++ случайные числа, чтобы создать лучшую форму(), но, что'какой-то вариант среднего уровня. Если вы не побеспокоились об особенностях ГСЧ, то это's также стоит инвестировать немного времени, чтобы понять, как базовые методы работы, потом предоставляем один. Так что вы've получили полный контроль над кодом, и вы можете гарантировать, что с таким же семян, последовательность всегда одна и та же, независимо от платформы или версии языка C++ вы ссылаетесь.