C++ C++;尝试将伯努利分布设置为函数的输出时出现问题

C++ C++;尝试将伯努利分布设置为函数的输出时出现问题,c++,random,bernoulli-probability,C++,Random,Bernoulli Probability,我需要我的程序来模拟伯努利(p)随机变量的能力,改变p。 如果我这样写smth #include <random> #include <iostream> #include <chrono> int main() { double prob = 0.1; //let it be const for now, no need to change it in this example std::mt19937 gen(std::chrono::steady_clo

我需要我的程序来模拟伯努利(p)随机变量的能力,改变p。 如果我这样写smth

#include <random>
#include <iostream>
#include <chrono>
int main()
{
double prob = 0.1; //let it be const for now, no need to change it in this example
std::mt19937 gen(std::chrono::steady_clock::now().time_since_epoch().count());
std::bernoulli_distribution coin(prob);

int success = 0;
for (int i = 0; i < 1000; ++i) {
  if (coin(prob)) ++success;
}
  std::cout << success << "\n";
    
  return 0;
}
#包括
#包括
#包括
int main()
{
double prob=0.1;//现在让它为常量,在本例中不需要更改它
标准::mt19937 gen(标准::时钟::稳定时钟::现在();
标准:伯努利分配币(prob);
int成功=0;
对于(int i=0;i<1000;++i){
如果(硬币(概率))++成功;
}

std::cout您不应该为每一卷创建一个新的随机数生成器,这会破坏整个伪随机性

创建一个全局(-ish)生成器,并在每次函数调用中重用它:

bool coin_flip(int switcher) {
    static std::mt19937 gen(std::chrono::steady_clock::now().time_since_epoch().count());

    switch(switcher)
    {
        case 1:
            std::bernoulli_distribution coin(0.1);
            return coin(gen);
        case 2:
            std::bernoulli_distribution coin(0.2);
            return coin(gen);
    }
    throw std::invalid_argument{"Incorrect switcher value"};
}

static
局部变量在第一次函数调用期间只初始化一次,在其他每次函数调用中都保持可访问性。它们在生命周期方面是全局的(它们只有在程序完成时才会消失),但只能从该函数中访问。

您不应该为每个卷创建一个新的随机数生成器,这会破坏整个伪随机性

创建一个全局(-ish)生成器,并在每次函数调用中重用它:

bool coin_flip(int switcher) {
    static std::mt19937 gen(std::chrono::steady_clock::now().time_since_epoch().count());

    switch(switcher)
    {
        case 1:
            std::bernoulli_distribution coin(0.1);
            return coin(gen);
        case 2:
            std::bernoulli_distribution coin(0.2);
            return coin(gen);
    }
    throw std::invalid_argument{"Incorrect switcher value"};
}

static
局部变量在第一次函数调用期间只初始化一次,在其他每次函数调用中都保持可访问性。它们在生命周期方面是全局的(它们只有在程序完成时才会消失),但只能从该函数中访问。

您可以创建一个
硬币
类,该类以给定的概率持有特定的分布,然后将该类的多个实例存储在一个容器中

#include <random>
#include <iostream>
#include <vector>

template< class Dist >
class Coin
{
    Dist dist_;

  public:
    Coin(double p) : dist_{p} {}

    template< class Gen >
    bool toss(Gen& gen) { return dist_(gen); }
};

int main()
{
    std::seed_seq ss{ 42, 987654321, 17, 65535 };
    std::mt19937 gen{ ss };

    using coin_t = Coin<std::bernoulli_distribution>;

    std::vector<coin_t> coins{
        0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9
    };

    std::vector<int> successes(coins.size());
    
    for (size_t i = 0; i < 1000; ++i) {
        for (size_t c = 0; c < coins.size(); ++c) {
            successes[c] += coins[c].toss(gen);
        }
    }

    for (auto s : successes) {
        std::cout << s << '\n';
    }
}
#包括
#包括
#包括
模板
等级硬币
{
距离距离;
公众:
硬币(双p):距离{p}{}
模板
bool-toss(Gen&Gen){返回距离(Gen)}
};
int main()
{
种子{42987654321,176535};
std::mt19937 gen{ss};
使用硬币=硬币;
矢量硬币{
0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9
};
std::向量成功(coins.size());
对于(尺寸i=0;i<1000;++i){
对于(大小c=0;cstd::cout您可以创建一个
Coin
类,以给定的概率持有一个特定的分布,然后将该分布的多个实例存储在一个容器中

#include <random>
#include <iostream>
#include <vector>

template< class Dist >
class Coin
{
    Dist dist_;

  public:
    Coin(double p) : dist_{p} {}

    template< class Gen >
    bool toss(Gen& gen) { return dist_(gen); }
};

int main()
{
    std::seed_seq ss{ 42, 987654321, 17, 65535 };
    std::mt19937 gen{ ss };

    using coin_t = Coin<std::bernoulli_distribution>;

    std::vector<coin_t> coins{
        0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9
    };

    std::vector<int> successes(coins.size());
    
    for (size_t i = 0; i < 1000; ++i) {
        for (size_t c = 0; c < coins.size(); ++c) {
            successes[c] += coins[c].toss(gen);
        }
    }

    for (auto s : successes) {
        std::cout << s << '\n';
    }
}
#包括
#包括
#包括
模板
等级硬币
{
距离距离;
公众:
硬币(双p):距离{p}{}
模板
bool-toss(Gen&Gen){返回距离(Gen)}
};
int main()
{
种子{42987654321,176535};
std::mt19937 gen{ss};
使用硬币=硬币;
矢量硬币{
0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9
};
std::向量成功(coins.size());
对于(尺寸i=0;i<1000;++i){
对于(大小c=0;cstd::cout Thx为答案。但是如果我需要十万个发电机呢?如果我在循环中提前创建它们。它们将占用大量内存。此外,我的任务假设我将创建r.v,这取决于以前模拟的结果。我可以提前创建所有可能的发电机,但这看起来像是过度杀戮,我不喜欢我更新了答案。再说一遍,我对地图不熟悉,需要一些时间来深入研究。我会看一下的later@Ilya68嗯,我想我可能做得太过分了。如果我没弄错的话,你唯一需要的全局元素就是生成器,每次都可以重新创建分布(仅调整发电机输出)。我需要考虑一下,稍后我会尝试更新答案。@Yksisarvinen同意前面的评论。我总是根据需要创建发行版,并且在文档中没有看到任何其他建议。RNG当然需要保留,但答案是AFAIKThx。但是如果我需要它怎么办还有数千个发电机?如果我在循环中提前创建它们。它们将占用大量内存。此外,我的任务假设我将根据以前的模拟结果创建r.v。我可以提前创建所有可能的发电机,但这看起来像是过度杀戮,我一点也不喜欢。@Ilya68我更新了答案。再次,我是不熟悉地图,需要一些时间来深入研究。我会看一看later@Ilya68嗯,我想我可能做得太过分了。如果我没有弄错的话,您需要的唯一全局元素是生成器,每次都可以重新创建分发版(分发版只调整生成器输出)。我需要考虑一下,稍后我会尝试更新答案。@Yksisarvinen同意前面的评论。我一直根据需要创建发行版,但在文档中没有看到任何其他建议。RNG当然需要保留,但没问题