C+中正态分布的随机数+; 作为C++初学者的一个完整的例子,我想从正态分布中生成一个随机数。p>

C+中正态分布的随机数+; 作为C++初学者的一个完整的例子,我想从正态分布中生成一个随机数。p>,c++,c++17,C++,C++17,通过以下代码(由此派生),我能够做到这一点: #include <iostream> #include <boost/random.hpp> #include <boost/random/normal_distribution.hpp> using namespace std; int main() { boost::mt19937 rng(std::time(0)+getpid()); boost::normal_distribut

通过以下代码(由此派生),我能够做到这一点:

#include <iostream>   
#include <boost/random.hpp>
#include <boost/random/normal_distribution.hpp>

using namespace std;

int main()
{
    boost::mt19937 rng(std::time(0)+getpid());
    boost::normal_distribution<> nd(0.0, 1.0);
    boost::variate_generator<boost::mt19937&,
                             boost::normal_distribution<> > rnorm(rng, nd);

    cout<< rnorm();
  return 0;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
boost::mt19937 rng(std::time(0)+getpid());
正态分布nd(0.0,1.0);
boost::变量发生器rnorm(rng,nd);

不能使用种子来初始化您的
生成器
。这里我使用的是基于时间的种子

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

using namespace std;

int main()
{
    unsigned seed = chrono::system_clock::now().time_since_epoch().count();
    default_random_engine generator(seed);
    normal_distribution<double> distribution(0.0, 1.0);

    cout << distribution(generator);
    return 0;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
unsigned seed=chrono::system_clock::now().time_since_epoch().count();
默认随机引擎生成器(种子);
正态分布(0.0,1.0);
库特
(1) 为什么会发生这种情况?我该如何解决

这是因为您默认构造了PRNG(伪随机数生成器)不要设定种子。PRNG生成一个确定的数字序列。序列通常很长,然后重新开始。种子用于设置PRNG的内部状态,也就是说,它的起点。如果没有种子,每次都将以相同的状态开始

(2) 有没有其他更简单的方法来生成随机数

<不,不使用现代标准C++(C++ 11和后)。< /P> 一些注意事项:

  • 基于时钟的一次采样使用基于时间的种子被认为是不好的,因为您有可能使用相同的值播种两个PRNG:s
  • 您的程序中只需要一个PRNG(每个需要生成随机数的线程),并且植入PRNG被认为是昂贵的(就速度而言)。因此,您可以将生成器设置为全局的,以便它可以在程序中的任何地方使用。下面是一个线程安全版本,初始化为True(但速度较慢)RNG,从熵池生成数字。
  • 如果您的
    random_设备
    缺少或有缺陷(早期版本的MinGW有缺陷的实现),您可以将
    random_设备
    输出与一些基于时间的数字(间隔一段时间采样)组合起来创建一个用于初始化PRNG的种子。以下内容应与错误和一致性实现一起使用,以创建难以预测的种子:

    #include <chrono>
    #include <thread>
    
    // Create a seed_seq with 2 time based numbers and 2 random_device numbers.
    // The two sleeps are done to ensure some diff in the clock counts.
    static std::seed_seq get_seed() {
        static constexpr auto min = std::chrono::steady_clock::duration::min();
        std::random_device rd;
        std::uint_least32_t si[4];
        for(size_t s = 0; s < std::size(si);) {
            si[s++] = rd();
            std::this_thread::sleep_for(min);
            si[s++] = static_cast<std::uint_least32_t>(
                std::chrono::steady_clock::now().time_since_epoch().count());
            std::this_thread::sleep_for(min);
        }
        return {si[0], si[1], si[2], si[3]};
    }
    
    std::mt19937& prng() {           // extern declared in a header file
        static thread_local std::seed_seq seed = get_seed();
        static thread_local std::mt19937 gen(seed);
        return gen;
    }
    
    #包括
    #包括
    //创建一个包含2个基于时间的数字和2个随机设备编号的种子序列。
    //进行两次休眠是为了确保时钟计数有所不同。
    静态std::seed_seq get_seed(){
    static constexpr auto min=std::chrono::staid_clock::duration::min();
    std::随机_装置rd;
    std::uint_least32_t si[4];
    对于(尺寸s=0;s

我不熟悉这些函数,但在C中,如果不给rand函数一个种子值,它也会生成相同的值,因为算法不是随机的,而是确定性的。因此,如果从相同的种子值开始(如果没有种子值,可能是0)它将是一样的。感谢所有的快速回复!我确实想了解发生了什么,而不仅仅是从其他地方复制和过去的代码。例如,我不知道我必须为生成器提供种子。在第一个版本中,您添加了种子“std::time(0)+getpid()”,在第二种情况下,您不需要。无论哪种方式,它都是伪随机的,因此对于同一种子,您会得到相同的“随机数”。在第二种情况下,您还可以调用generator.seed(std::time(0)+getpid());以获得与第一个类似的效果version@user213544你有C++11编译器吗?如果有,用标准头
代替
。旁注:为什么建议在基于
的随机设备上使用基于时间的种子呢?@TedLyngmo corner case-MinGW对
随机设备的实现产生了同样的结果,deterministic值,这使得它在这种情况下毫无用处。因此,上述解决方案是优越的,但我不知道它是否适用于其他地方。@Fureeish“std::random_设备具有确定性的一个著名实现是MinGW的旧版本(错误338,自GCC 9.2以来修复),尽管存在替代实现,例如mingw-std-random_设备。最新的mingw版本可以从GCC下载,并带有MCF线程模型。”-因此,与其调整代码以支持不一致的实现,不如尝试获得一个一致的实现,并且使用MinGW,这是可能的。:-@user213544
default\u random\u engine
是实现定义的,因此很难给出一个通用的答案。
mt19937
在标准中被锁定为特定的如果我没有弄错的话,
Mersenne Twister
的n版本。我不确定
boost
是否使用相同的实现。但是,与标准中包含的PRNG:s相比,PRNG:s速度更快、性能更好。@user213544在有性能要求之前,您不必担心性能。
std::mt19937& prng() {           // extern declared in a header file
    static thread_local std::mt19937 gen(std::random_device{}());
    return gen;
}
#include <chrono>
#include <thread>

// Create a seed_seq with 2 time based numbers and 2 random_device numbers.
// The two sleeps are done to ensure some diff in the clock counts.
static std::seed_seq get_seed() {
    static constexpr auto min = std::chrono::steady_clock::duration::min();
    std::random_device rd;
    std::uint_least32_t si[4];
    for(size_t s = 0; s < std::size(si);) {
        si[s++] = rd();
        std::this_thread::sleep_for(min);
        si[s++] = static_cast<std::uint_least32_t>(
            std::chrono::steady_clock::now().time_since_epoch().count());
        std::this_thread::sleep_for(min);
    }
    return {si[0], si[1], si[2], si[3]};
}

std::mt19937& prng() {           // extern declared in a header file
    static thread_local std::seed_seq seed = get_seed();
    static thread_local std::mt19937 gen(seed);
    return gen;
}