使平均值产生随机数生成器

时间:2018-10-16 19:30:42

标签: c++ random numbers

我需要使随机数生成器不具有内置函数并且平均值不大于0.5。 它必须生成10000个数字,最好不要重复。 例如下面的PRNG代码:

#include <iostream>
using namespace std;

unsigned int Rand()
{
    static unsigned int seed = 5323;
    seed = 8253729 * seed + 2396403;
    return seed  % 32768;
}

int main()
{
    for (int count=1; count <= 10000; ++count)
{
        cout << Rand() << "\t";
        if (count % 10 == 0)
        cout << "\n";
}

    return 0;
}

结果是我有10000个数字,如果我尝试从第一行计算10个数字的平均值,我将不会收到0.5。例如,在第一行中,我们收到:

31222,24489,32444,25391,6402,11317,10440,6843,3598,3777

平均值是:15592.3。 我该怎么做才能降低该值?

2 个答案:

答案 0 :(得分:1)

不要尝试投放自己的PRNG

如果您获得了密码学学位,或者以其他方式最终专注于PRNG开发,那么您将在学习或培训中学到必要的技术。在这种情况下尝试这样做只会给您带来不好的结果。

使用<random>

C ++具有库功能,旨在使此类问题尽可能轻松地解决。

#include<random>
#include<iostream>

float get_random_value() {
    static std::default_random_engine engine{std::random_device()()};
    static std::uniform_real_distribution<float> distribution{0, 1};

    return distribution(engine);
}

int main() {
    for (int count=1; count <= 10000; ++count) {
        std::cout << get_random_value() << "\t";
        if (count % 10 == 0)
            std::cout << "\n";
    }
}

此代码的组件如下所示:

  • std::default_random_engine是您的库实现认为适合默认使用的任何PRNG的别名。这通常默认为std::mt19937,这是一种PRNG类型,称为“ Mersenne Twister”。 <random>参考包含许多其他引擎,您可以考虑使用。
  • std::random_device是一种库功能,用于从操作系统请求“熵”。您需要担心的是,它只能被构造一次,被调用以生成“种子”,然后被丢弃并且不再使用。如果您不使用此代码,或者您硬编码了此调用返回的值,则每次运行程序时,引擎将始终以相同的顺序生成相同的值。
  • std::uniform_real_distribution是一个发行版。使用为此分发指定的参数,可以直接指定分发的范围。我们使用了01,因此分布将返回0到1之间的均匀分布的数字。还有其他可用的分布,您可以在参考资料中找到它们。
  • 使用引擎作为唯一参数,获取值就像在分发对象上调用调用运算符一样容易。

此代码将可靠地生成[0,1)范围内的数字,并且以惯用的表示方式进行。如果您需要不同范围内的统一值,则可以轻松调整此代码以进行处理。如果您需要非均匀值(例如正态分布),则可以使用其他分布(例如std::normal_distribution)来正确处理这种情况。

答案 1 :(得分:0)

Rand() / 32767.0的平均值为0.5。

您需要的是有关数学和统计学的知识。搜索期望,均匀分布。