如何生成随机数的最佳方式?
你应该使用<random>
:
#include <random>
typedef std::mt19937 rng_type;
std::uniform_int_distribution<rng_type::result_type> udist(0, 7);
rng_type rng;
int main()
{
// seed rng first:
rng_type::result_type const seedval = get_seed(); // get this from somewhere
rng.seed(seedval);
rng_type::result_type random_number = udist(rng);
return random_number;
}
在 C++11 之前,你可以在 TR1 (<tr1/random>
, std::tr1::mt19937
等等) 或 Boost.random 中找到它们,两者的接口基本相同(尽管存在细微差异)。
auto rand = bind(uniform_int_distribution<>(0,7),mt19937(get_seed()));
- bames53bind
,但如果你想要更紧凑的形式,那当然可以。 - Kerrek SBstd::random_device
。结果的质量取决于你的实现,但这是一个开始。 - Kerrek SB那么您可以考虑使用以下C风格解决方案,为了这个社区的声誉(请参见rand() Considered Harmful),代码已经被划掉了:
这是一个简单的C风格函数,它生成从min
到max
之间的随机数,包括两端。这些数字似乎非常接近均匀分布。
int irand(int min, int max) {
return ((double)rand() / ((double)RAND_MAX + 1.0)) * (max - min + 1) + min;
}
srand
函数:int occurrences[8] = {0};
srand(time(0));
for (int i = 0; i < 100000; ++i)
++occurrences[irand(1,7)];
for (int i = 1; i <= 7; ++i)
printf("%d ", occurrences[i]);
输出:14253 14481 14210 14029 14289 14503 14235
另外看看:
在范围内生成随机数?
均匀地在整个范围内生成随机数
并找时间观看前11分钟的视频
irand
实现并不能产生均匀分布的随机数:正如 rand() considered harmful 中所解释的那样,某些值比其他值更有可能出现。你的示例在视频的 7:30 处有描述。 - syam<random>
可用,为什么不选择它呢?它更清晰和更好的解决方案。它也可以像我的irand
一样封装成一个独立的帮助函数。 - LihO<random>
,只是指出还有更糟糕的错误可以犯。当然如果有<random>
可用,应优先考虑它,但是如果你必须使用rand()
,那么你的解决方案可能是我们能够得到的最好的(之一)。 - syamrand()
对我的单元测试非常有用。但在 Unix 系统上,你至少可以从 /dev/random
或 /dev/urandom
加载字节。此外,OpenSSL 库提供了 RAND(尝试 man RAND
和 man RAND_bytes
)。 - Alexis WilkeBoost.Random是一个出色的库,用于生成伪随机数(如果平台支持,则可以生成真正的随机数)。
random_device
(与现在标准的<random>头文件一样)以提供对非确定性均匀随机数生成器的访问,该生成器在具有此类设备的平台上可用。(例如,操作系统通过观察网络流量等活动收集随机数据,并通过/dev/random提供对该数据的访问) - bames53我的“随机”库提供了一个方便的C++11随机类的封装。你可以通过一个简单的“get”方法完成几乎所有的事情。
例如:
auto val = Random::get(-10, 10); // 整数
auto val = Random::get(10.f, -10.f); // 浮点数
auto val = Random::get<bool>( ) // 生成true的概率为0.5%
auto val = Random::get<bool>( 0.7 ) // 生成true的概率为0.7%
auto val = Random::get( { 1, 3, 5, 7, 9 } ); // val = 1 or 3 or...
auto it = Random::get( vec.begin(), vec.end() ); // it = 随机迭代器
auto it = Random::get( vec ); // 返回随机迭代器
甚至还有更多!请查看 GitHub 页面:
rand
不好使用? - David Schwartzrand
函数?" - 请参考rand()被认为是有害的。 - Jesper Juhl