制作具有平均值的随机数生成器

Make Random Numbers Generator with average value

本文关键字:随机数生成器 平均值      更新时间:2023-10-16

我需要在没有内置函数且平均值不超过 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。 我可以用它做什么来降低这个值?

不要试图滚动自己的 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。<random>引用包含许多其他可以考虑的引擎。
  • std::random_device是一个库功能,用于从操作系统请求"熵"。你只需要担心的是,这是一次构造的,调用以生成"种子",然后丢弃并且不再使用。如果不使用它,或者对此调用返回的值进行硬编码,则每次运行程序时,引擎将始终以相同的顺序生成相同的值。
  • std::uniform_real_distribution是一个分布。使用为此分布指定的参数,可以直接指定分布的范围。我们使用了01,因此分布将返回 0 到 1 之间的均匀分布数字。还有其他可用的发行版,您可以在参考中找到描述。
  • 获取值就像调用分布对象上的调用运算符一样简单,使用引擎作为其唯一参数。

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

Rand() / 32767.0

的平均值为 0.5。

你需要的是数学、统计学方面的知识。寻找期望,均匀分布。