【问题标题】:C++ Generating random numbers in functionsC++ 在函数中生成随机数
【发布时间】:2018-01-19 22:41:19
【问题描述】:

对于我正在处理的项目,我需要在函数中生成一个随机数向量。问题是我最终每次都生成相同的数字向量。我有这个例子可以重现我的问题:

#include <iostream>
#include <random>

std::vector<double> generate(std::default_random_engine generator, double mean, double sigma, int n)
{
    std::vector<double> generated(n,0);
    std::normal_distribution<double> distribution(mean,sigma);
    for (int i = 0;i<n;i++)
        generated[i] = distribution(generator);
    return generated;
}
std::vector<double> generate(double mean, double sigma, int n)
{
    std::vector<double> generated(n,0);
    std::default_random_engine generator;
    std::normal_distribution<double> distribution(mean,sigma);
    for (int i = 0;i<n;i++)
        generated[i] = distribution(generator);
    return generated;
}

int main(int argc, char** argv)
{
    // Read inputs
    int nrolls = 20;  // number of experiments
    int ntimes = 50;
    double mean = 100;
    double sigma = 4;
    bool useFunction(false);
    if (argc>1)
        useFunction=true;

    // crates series
    std::vector< std::vector<double> > results(ntimes,std::vector<double>());
    std::default_random_engine generator;
    for (int i = 0;i<ntimes/4;i++){
        std::vector<double> generated(nrolls,0);
        std::normal_distribution<double> distribution(mean,sigma);
        for (int i = 0;i<nrolls;i++)
            generated[i] = distribution(generator);
        results[i] = generated;
    }
    for (int i = ntimes/4;i<ntimes/2;i++)
        results[i] = generate(generator,mean,sigma,nrolls);
    for (int i = ntimes/2;i<3*ntimes/4;i++){
        std::vector<double> generated(nrolls,0);
        std::normal_distribution<double> distribution(mean,sigma);
        for (int i = 0;i<nrolls;i++)
            generated[i] = distribution(generator);
        results[i] = generated;
    }
    for (int i = 3*ntimes/4;i<ntimes;i++)
        results[i] = generate(mean,sigma,nrolls);
     //

    // Display all random numbers
    for (int i = 0;i<ntimes;i++){
        std::cout<<i;
        for (int j = 0;j<nrolls;j++)
            std::cout<<" "<<results[i][j];
        std::cout<<std::endl;
    }

    // Check number of equal results
    int n_equal(0);
    int n_total(0);
    for (int i=0;i<ntimes;i++){
        for (int k = 0;k<nrolls;k++){
            for (int j=i+1;j<ntimes;j++){
                n_total++;
                if (results[i][k] == results[j][k])
                    n_equal++;
            }
        }
    }
    std::cout<<n_equal<<"/"<<n_total<<std::endl;

    // Exit
    return 0;
}

我试图通过将生成器传递给生成随机数数组的函数来解决它,但显然它也不起作用。有人可以提示我每次调用生成函数时我应该如何获取不同的数组吗?

非常感谢。

【问题讨论】:

  • 您可以为您的引擎播种以每次获得不同的值

标签: c++ random normal-distribution


【解决方案1】:

在玩了一会儿之后,我发现最好为新的 C++ 随机生成器使用全局变量。而且你应该每个随机数套件都有一个,所以你(统计上几乎:) 100% 肯定会得到指定的分布。

伪随机生成器本质上是静态的野兽,因为它们保留上次计算中生成的数字以生成下一次。

【讨论】:

    【解决方案2】:

    这里有两个问题。首先

    std::vector<double> generate(std::default_random_engine generator, double mean, double sigma, int n)
    

    按值获取PRNG,这意味着它会进行复制。这意味着每次调用该函数时,您都将从相同的序列开始,因为您从不从调用站点修改生成器。

    第二个问题是

    std::vector<double> generate(double mean, double sigma, int n)
    

    每次调用函数时都会重新创建相同的生成器。这是行不通的,因为它每次都会创建相同的序列。

    通常您有两种选择。您可以通过引用将 PRNG 传递给函数,或者在函数中声明 static PRNG,以便它在函数调用之间保持不变。

    【讨论】:

    • 我认为我的问题来自 PRNG,但不知道为什么。两种解决方案都运行良好!!非常感谢您的帮助!!
    • @apalomer 没问题。很高兴为您提供帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-29
    • 2019-05-15
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    相关资源
    最近更新 更多