C ++为每个新对象使用相同的default_random_engine

时间:2015-05-28 22:34:35

标签: c++ random static normal-distribution

我是来自Java和C#背景的C ++初学者。我正在尝试在每次创建新对象时使用相同的default_random_enginenormal_distribution<double>。之前我在每个构造函数中使用带有新种子和新default_random_engine的新normal_distribution<double>。我认为normal_distribution无法正常工作。

旧代码 - &gt;

my_object.cpp:

default_random_engine generator;

MyObject() {
    double mean = 1.0;
    double std = 0.5;
    normal_distribution<double> distribution(mean, std);
    QTime time = QTime::currentTime();
    uint milli = (time.hour() * 60 * 60 * 1000) + (time.minute() * 60 * 1000) + (time.second() * 1000) + time.msec();
    generator.seed(milli);
    myValue = distribution(generator);
}

此编译和myValue的值是随机分布的。我只是认为它们与正态分布不匹配,因为我总是创建一个新的default_random_engine和normal_distribution并使用了一个新的种子。

我的新代码 - &gt;

main.h:

class Main
{
   public:
       static default_random_engine generator;
       static normal_distribution<double> distribution;
};

main.cpp中:

default_random_engine generator;
normal_distribution<double> distribution;

int main(int argc, char *argv[]) {
    double mean = 1.0;
    double std = 0.5;
    distribution(mean, std);
    QTime time = QTime::currentTime();
    uint milli = (time.hour() * 60 * 60 * 1000) + (time.minute() * 60 * 1000) + (time.second() * 1000) + time.msec();
    generator.seed(milli);
}

my_object.cpp:

default_random_engine generator;
normal_distribution<double> distribution;

MyObject() {
    myValue = distribution(generator);
}

但是现在我在编译时遇到了10个错误:

error C2228: left of '.min' must have class/struct/union
error C2780: '_Rty std::_Nrand(_Engine &,long double,_Rty)' : expects 3 arguments - 2 provided
error C2780: '_Rty std::_Nrand(_Engine &,double,_Rty)' : expects 3 arguments - 2 provided
...

我做错了什么?为什么我会收到错误?我是否更正以前我的正常分布/随机生成不正确?我能以这种方式产生所需的正态分布吗?

2 个答案:

答案 0 :(得分:3)

其中一个问题是

distribution(mean, std);

这一行不符合你的想法。要设置分布的参数,请使用std::normal_distribution<>::param()函数,如

distribution.param(std::normal_distribution<double>(mean,std).param());

或(感谢@Praetorian)

distribution.param(decltype(distribution)::param_type(mean, std));

此外,您的distribution似乎是class Main内的静态对象,但您可以在.cpp文件中定义另一个静态对象。如果您只是想要第一个ODR,请使用

normal_distribution<double> Main::distribution;

而是随后使用Main::distribution代替distribution。引擎也一样。

答案 1 :(得分:2)

我想在这里得到了其他答案的帮助,我解决了我的问题。我在“Main”中创建并初始化default_random_engine,normal_distribution和random_device,并在“MyClass”中使用extern关键字。如果我没有错,每次创建一个新的“MyClass”对象时,它应该使用相同的随机生成器,这样我就可以得到我想要的正态分布。

Main.cpp的

#include "Main.h"
#include "MyClass.h"

#include <iostream>
#include <random>

using namespace std;

normal_distribution<double> distribution;
default_random_engine engine;
random_device rd;

int main(int argc, char *argv[]) {
    double mean = 1.0;
    double std = 0.5;
    distribution.param(std::normal_distribution<double>(mean, std).param());
    engine.seed(rd());
    MyClass obj = MyClass();        
    return 0;
}

MyClass.h:

#pragma once
class MyClass
{
public:
    MyClass();
    double value;
};

MyClass.cpp:

#include "MyClass.h"

#include <random>

using namespace std;

extern default_random_engine engine;
extern normal_distribution<double> distribution;

MyClass::MyClass()
{
    value = distribution(engine);
}