c++中随机数的播种问题

problems in seeding random number in c++

本文关键字:问题 随机数 c++      更新时间:2023-10-16

我使用下面的代码(从网上某处复制)并设法生成一些随机数数组。

std::default_random_engine generator;
std::uniform_real_distribution<double> distribution(0,1);
int N;
std::cout<< "Please enter the number of disks to be generated: ";
std::cin>> N;
// generates N pairs of coordinates
double** R;
R = new double* [N];
for (int i=0; i<N; i++) {
    R[i] = new double [3];
    for (int j=0; j<3; j++) {
        R[i][j] = distribution(generator);
    }
}

问题是输出总是相同的,所以我认为它没有正确播种。然后我从网上找到了以下代码,但它在我的计算机上不起作用(我总是得到运行时错误)

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';

上面的代码有什么问题?如何播种我的代码,以便我每次都能得到不同的输出?此外,对于第一个代码,是否使用线性同余算法?如何使用"更好"的算法,如Mersenne Twister (mt19937) ?

谢谢

default_random_engine是实现定义的。没有指定使用哪个算法。

你得到哪个runtime_error ?它应该正确工作,但作为解决方案,您可以将mt19937srand一起使用当前时间。

std::mt19937 gen(static_cast<std::mt19937::result_type>(std::time(nullptr)));

您需要在构造函数中显式地设置随机数生成器的种子,如下所示(本例使用系统时钟来唯一地设置生成器的种子):

  // obtain a seed from the timer
  unsigned seed = myclock::now().count();
  //construct the generator
  std::default_random_engine generator(seed);

您需要为随机数生成器提供一个随机种子。(顺便说一句,库默认在生成器中生成相同的数字,因此测试结果可以预测)。我使用的系统时间和其他人展示的一样。

我没有看到提到的一个方法是std::seed_seq,它解决了这个问题。Feed是几个整数,它产生一个很好的种子序列:

#include <random>
#include <vector>
#include <array>
#include <iostream>
#include <iomanip>
#include <chrono>
unsigned long
system_now()
{
  std::chrono::system_clock::time_point now{std::chrono::system_clock::now()};
  std::chrono::system_clock::duration epoch{now.time_since_epoch()};
  return static_cast<unsigned long>(now.time_since_epoch().count());
}
int
main()
{
    // ...
    auto N = 500;
    std::vector<std::array<double, 3>> R(N);
    std::seed_seq seq{1, 2, 3, 4, 5};
    std::vector<std::uint32_t> seeds(1000);
    seq.generate(seeds.begin(), seeds.end());
    std::mt19937 generator(seeds[system_now() % seeds.size()]);
    std::uniform_real_distribution<double> distribution{0.0, 1.0};
    for (auto & V : R)
        for (auto & C : V)
            C = distribution(generator);
    for (const auto & V : R)
    {
        std::cout << '(';
        for (const auto & C : V)
            std::cout << ' ' << std::setw(10) << C;
        std::cout << " )n";
    }
}

警告!种子序列也是可重复的-具有相同的输入,它返回相同的输出!同时,当你拥有1000个种子时,你将再次设置相同的数字。相同的种子,相同的生成数