std::mt19937 不是 return 随机数
std::mt19937 doesn't return random number
我有如下一段代码:
unsigned int randomInt()
{
mt19937 mt_rand(time(0));
return mt_rand();
};
如果我调用此代码,例如在 for 循环中调用 4000 次,我不会得到随机无符号整数,而是得到一个值的 1000 次,接下来的 1000 次我得到下一个值。
我做错了什么?
随机源是属于您的整个程序的资源,而不是属于单个函数的资源。您应该 永远不要 在用于 return 随机值的例程中创建随机源。
好的选项包括:
- 将随机源传递到您的函数中
- 将随机源设为全局变量
- 将随机源设为静态变量,以便初始化只发生一次。
您可能想尝试但不应该做的一件事是用分辨率更高的类似函数替换time(0)
;虽然您会得到不同的结果,但这仍然会生成质量较差的随机数,甚至可能比正确生成随机数慢得多。 (我相信有一些随机数生成器 可以 在这种情况下正常工作,但必须为此目的而设计)
发生这种情况是因为您在一个循环中调用了 f
4000 次,这可能需要不到一英里秒,因此在每次调用 time(0)
returns 时都使用相同的值,因此初始化具有相同种子的伪随机生成器。正确的方法是一劳永逸地初始化种子,最好通过 std::random_device
,像这样:
#include <random>
#include <iostream>
static std::random_device rd; // random device engine, usually based on /dev/random on UNIX-like systems
// initialize Mersennes' twister using rd to generate the seed
static std::mt19937 rng{rd()};
int dice()
{
static std::uniform_int_distribution<int> uid(1,6); // random dice
return uid(rng); // use rng as a generator
}
int main()
{
for(int i = 0; i < 10; ++i)
std::cout << dice() << " ";
}
我有如下一段代码:
unsigned int randomInt()
{
mt19937 mt_rand(time(0));
return mt_rand();
};
如果我调用此代码,例如在 for 循环中调用 4000 次,我不会得到随机无符号整数,而是得到一个值的 1000 次,接下来的 1000 次我得到下一个值。
我做错了什么?
随机源是属于您的整个程序的资源,而不是属于单个函数的资源。您应该 永远不要 在用于 return 随机值的例程中创建随机源。
好的选项包括:
- 将随机源传递到您的函数中
- 将随机源设为全局变量
- 将随机源设为静态变量,以便初始化只发生一次。
您可能想尝试但不应该做的一件事是用分辨率更高的类似函数替换time(0)
;虽然您会得到不同的结果,但这仍然会生成质量较差的随机数,甚至可能比正确生成随机数慢得多。 (我相信有一些随机数生成器 可以 在这种情况下正常工作,但必须为此目的而设计)
发生这种情况是因为您在一个循环中调用了 f
4000 次,这可能需要不到一英里秒,因此在每次调用 time(0)
returns 时都使用相同的值,因此初始化具有相同种子的伪随机生成器。正确的方法是一劳永逸地初始化种子,最好通过 std::random_device
,像这样:
#include <random>
#include <iostream>
static std::random_device rd; // random device engine, usually based on /dev/random on UNIX-like systems
// initialize Mersennes' twister using rd to generate the seed
static std::mt19937 rng{rd()};
int dice()
{
static std::uniform_int_distribution<int> uid(1,6); // random dice
return uid(rng); // use rng as a generator
}
int main()
{
for(int i = 0; i < 10; ++i)
std::cout << dice() << " ";
}