首页 > 解决方案 > 本地 std::bernoulli_distribution 如何创建准确分布的数据?

问题描述

在这里,我有一个类Generator,它有一个随机数引擎和一个方法genTrial(),它应该返回一个bool表示独立试验的“成功”或“失败”结果的方法。使用 std::bernoulli_distribution,我可以分配获得“成功”的概率;注意这个变量是本地的genTrial()

在主代码中,我通过genTrial()在循环中以 25% 的成功参数重复调用来生成 30,000 次试验。当代码运行时,分布是正确的。

我的问题是:由于std::bernoulli_distribution变量是本地的,它如何知道/记住分布的状态以便仍然生成正确的数据集?如果每次迭代都创建/销毁一个新变量,那么就没有状态的持久性,也无法知道过去做了什么,那么它如何确定将馈入数放在哪里?不应该把数字放在同一个集合中吗?

生成器.h

#ifndef GENERATOR_H
#define GENERATOR_H




#include <random>


class Generator
{
    private:
        static std::mt19937 randEngine;

    public:
        bool genTrial(double success);
};







#endif

生成器.cpp

#include "generator.h"
#include <cstdlib>
#include <random>






std::mt19937 Generator::randEngine(0);





bool Generator::genTrial(double success)
{
    std::bernoulli_distribution distrib(success);
    return distrib(randEngine);
}

主文件

#include "generator.h"
#include <iostream>

int main()
{
    const int NUM_SAMPLES = 30000;
    const int NUM_OF_BINARY_VALUES = 2;
    const double SUCCESS_RATE = 0.25;

    Generator gen;
    int binaryRecord[NUM_OF_BINARY_VALUES] = {0};

    // "roll the dice"
    for(int x = 0; x < NUM_SAMPLES; x++)
    {
        bool thisRoll = gen.genTrial(SUCCESS_RATE);
        if(thisRoll == true) binaryRecord[1]++;
        else binaryRecord[0]++;
    }

    // draw the results
    for(int y = 0; y < NUM_OF_BINARY_VALUES; y++)
    {
        if(y == 0) std::cout << "[F]: ";
        else std::cout << "[T]: ";

        int numActualTallies = binaryRecord[y];
        int numDisplayedTallies = numActualTallies / 1000;
        for(int i = 0; i < numDisplayedTallies; i++)
        {
            std::cout << "*";
        }
        std::cout << "\n";
    }
    return 0;
}

标签: c++

解决方案


唯一std::bernoulli_distribution成立的状态是在构建过程中使用的p分布参数。它不需要记住以前的输出值来输出具有正确分布的下一个值。例如,它可以double从给定的随机引擎生成一个随机数,true如果值小于p则返回。

您的函数每次调用时都会构造一个新分布,并传递相同的p参数值SUCCESS_RATE。您可以将代码重写为仅构造distrib一次。这可能比每次都构建它更有效,但结果将是相同的,即出现 25% 时间的bool值流。true


推荐阅读