Выбор генератора случайных чисел во время выполнения в CPP - PullRequest
1 голос
/ 07 июля 2019

Я, вероятно, прилагаю больше усилий, чем необходимо, но кого это волнует, давайте попробуем решить эту проблему: я хотел бы использовать генератор "random_device" из <random> в моем коде.Но это может быть недоступно в некоторых системах (в соответствии со спецификациями), поэтому я хотел бы иметь mt19937 в качестве резервной копии (но какой бы генератор я ни использовал, мне бы хотелось, чтобы в конце было одно и то же имя переменной).Теперь я могу попробовать random_device, чтобы увидеть, работает ли он, но что тогда?Если я использую оператор if, мой генератор исчезнет после if.Если я это объявлю, я не смогу потом изменить тип.Ниже кода, который не работает.

bool random_working=true;
try
{
    random_device rd; //throws exception when not able to construct
}
catch(exception& e)
{
    cout<<"Exception: ''random_device'' not working, switching back to mt19937"<<endl;
    random_working=false;
}
if(random_working)
    random_device mc; //for _M_onte-_C_arlo
else
        mt19937 mc;

1 Ответ

0 голосов
/ 07 июля 2019

В этой документации говорится, что std::random_device может быть детерминированным источником на некоторых платформах, что приводит к всегда одинаковой последовательности.

Вы всегда можете сохранить std::mt19937 и seed() с чем-то зависящим от времени, как в старые добрые времена std::rand() и std::srand().

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

Например

#include <iostream>
#include <random>
#include <chrono>

int
main()
{
  //-- create and seed a general purpose random generator --
  using gen_t = std::mt19937;
  const auto now{std::chrono::system_clock::now().time_since_epoch()};
  const auto seed=gen_t::result_type(
    std::chrono::duration_cast<std::chrono::microseconds>(now).count());
  gen_t rndGen{seed};

  //-- create a uniform distribution of integer values in [0;255] --
  std::uniform_int_distribution<int> uniDist{0, 255};

  //-- draw a random integer value --
  const int guessThatInteger=uniDist(rndGen);

  std::cout << guessThatInteger << '\n';
  return 0;
}
...