简体   繁体   English

C ++在函数中生成随机数

[英]C++ Generating random numbers in functions

For a project that I am working on I need to generate a vector of random numbers within a function. 对于我正在从事的项目,我需要在函数中生成随机数向量。 The problem is that I end up generating the same vector of numbers each time. 问题是我最终每次都会生成相同的数字向量。 I have this example that reproduces my problem: 我有这个例子重现了我的问题:

#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;
}

I have tried to solve it by passing the generator to the function where the array of random numbers is generated but apparently, it does not work either. 我试图通过将生成器传递给生成随机数数组的函数来解决此问题,但显然,它也不起作用。 Can somebody give me a hint on how should I do it to get different arrays each time i call the generate function? 有人可以提示我每次调用generate函数时如何获取不同的数组吗?

Thank you very much. 非常感谢你。

You have two problems here. 您在这里有两个问题。 First 第一

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

Takes the PRNG by value, which means it makes a copy. 按值获取PRNG ,这意味着将进行复制。 That means every time you call the function your going to be starting from the same sequence since you never modify the generator from the call site. 这意味着每次调用该函数都将以相同的顺序开始,因为您从未从调用站点修改过生成器。

The second issue is with 第二个问题是

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

You recreate the same generator every time you call the function. 每次调用该函数时,都将重新创建相同的生成器。 This is not going to work as it is going to create the same sequence each time. 这将不起作用,因为每次都会创建相同的序列。

Typically you have two options. 通常,您有两个选择。 You can pass the PRNG to the function by reference, or you declare a static PRNG in the function so it persists between function calls. 您可以通过引用将PRNG传递给函数,也可以在函数中声明static PRNG,以使其在函数调用之间持久存在。

After playing a bit with them, I found it best to use global variables for the new C++ random generators. 与他们玩了一会之后,我发现最好将全局变量用于新的C ++随机生成器。 And you should have one per random number suite, so you're (statistically almost :) 100% sure to get the distribution specified. 每个随机数套件都应该有一个,因此(统计上几乎是:)您100%一定要指定分配。

Pseudo-random generators are static beasts by nature, since they keep numbers generated in the last computation to generate the next. 伪随机生成器本质上是静态的野兽,因为它们保留在上一次计算中生成的数字以生成下一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM