如何使用< random>替换rand()?
C ++ 11引入了标头<random>
,其中包含用于随机数引擎和随机分布的声明.太好了-是时候替换rand()
的那些用法了,这在各种方式上通常都是有问题的.但是,如何替换似乎远非如此
C++11 introduced the header <random>
with declarations for random number engines and random distributions. That's great - time to replace those uses of rand()
which is often problematic in various ways. However, it seems far from obvious how to replace
srand(n);
// ...
int r = rand();
根据声明,似乎可以构建如下所示的统一分布:
Based on the declarations it seems a uniform distribution can be built something like this:
std::default_random_engine engine;
engine.seed(n);
std::uniform_int_distribution<> distribution;
auto rand = [&](){ return distribution(engine); }
这种方法似乎相当复杂,与使用srand()
和rand()
不同,我肯定不会记得这种方法.我知道 N4531 ,但即使如此,参与其中.
This approach seems rather involved and is surely something I won't remember unlike the use of srand()
and rand()
. I'm aware of N4531 but even that still seems to be quite involved.
是否有一种相当简单的方法来替换srand()
和rand()
?
Is there a reasonably simple way to replace srand()
and rand()
?
是否有一种相当简单的方法来替换srand()和rand()?
Is there a reasonably simple way to replace srand() and rand()?
完全公开:我不喜欢rand()
.不好,很容易被滥用.
Full disclosure: I don't like rand()
. It's bad, and it's very easily abused.
C ++ 11随机库填补了很长一段时间以来一直缺乏的空白.高质量随机库的问题在于它们通常很难使用. C ++ 11 <random>
库在这方面代表了巨大的进步.几行代码,我有一个很好的生成器,其表现非常好,并且可以轻松地从许多不同的分布生成随机变量.
The C++11 random library fills in a void that has been lacking for a long, long time. The problem with high quality random libraries is that they're oftentimes hard to use. The C++11 <random>
library represents a huge step forward in this regard. A few lines of code and I have a very nice generator that behaves very nicely and that easily generates random variates from many different distributions.
鉴于上述情况,我对您的回答有点异端.如果rand()
足以满足您的需求,请使用它.与rand()
一样糟糕(而且很糟糕),将其删除将代表C语言的重大突破.只需确保rand()
的缺点确实足以满足您的需求.
Given the above, my answer to you is a bit heretical. If rand()
is good enough for your needs, use it. As bad as rand()
is (and it is bad), removing it would represent a huge break with the C language. Just make sure that the badness of rand()
truly is good enough for your needs.
C ++ 14未弃用rand()
;它仅弃用C ++库中使用rand()
的函数.尽管C ++ 17可能会弃用rand()
,但它不会删除它.这意味着rand()
消失之前还有几年.当C ++委员会最终确实从C ++标准库中删除rand()
时,您将退休或改用其他语言的可能性很高.
C++14 didn't deprecate rand()
; it only deprecated functions in the C++ library that use rand()
. While C++17 might deprecate rand()
, it won't delete it. That means you have several more years before rand()
disappears. The odds are high that you will have retired or switched to a different language by the time the C++ committee finally does delete rand()
from the C++ standard library.
我正在创建随机输入,以使用类似于
std::vector<int> v(size); std::generate(v.begin(), v.end(), std::rand);
您不需要为此使用加密安全的PRNG.您甚至都不需要Mersenne Twister.在这种情况下,rand()
可能足以满足您的需求.
You don't need a cryptographically secure PRNG for that. You don't even need Mersenne Twister. In this particular case, rand()
probably is good enough for your needs.
更新
在C ++ 11随机库中,可以很好地替换rand()
和srand()
:std::minstd_rand
.
Update
There is a nice simple replacement for rand()
and srand()
in the C++11 random library: std::minstd_rand
.
#include <random>
#include <iostream>
int main ()
{
std:: minstd_rand simple_rand;
// Use simple_rand.seed() instead of srand():
simple_rand.seed(42);
// Use simple_rand() instead of rand():
for (int ii = 0; ii < 10; ++ii)
{
std::cout << simple_rand() << '\n';
}
}
函数std::minstd_rand::operator()()
返回std::uint_fast32_t
.但是,该算法将结果限制在1到2 31 -2(含)之间.这意味着结果将始终安全地转换为std::int_fast32_t
(如果int
至少为32位长,则转换为int
).
The function std::minstd_rand::operator()()
returns a std::uint_fast32_t
. However, the algorithm restricts the result to between 1 and 231-2, inclusive. This means the result will always convert safely to a std::int_fast32_t
(or to an int
if int
is at least 32 bits long).