如何使用c++ 11标准库生成随机数
How do I generate a random number using the C++11 standard library
新的c++ 11标准有整整一章专门介绍随机数生成器。但是,我如何执行最简单、最常见的任务,这些任务过去是这样编码的,但不依赖于标准的C库:
<>之前将srand ((unsigned int)时间(0));Int I = rand();对于随机数引擎、分布和种子是否存在合理的默认值?
您应该能够做如下操作:
std::default_random_engine e((unsigned int)time(0));
int i = e();
default_random_engine
的质量取决于实现。您也可以使用std::min_rand0
或std::min_rand
。
可能一个更好的方法来播种一个随机引擎是真正的随机数,因为可以从实现,而不是使用time
。
。
std::random_device rd;
std::default_random_engine e( rd() );
统一和简化已经提供的一些示例,我将总结为:
// Good random seed, good engine
auto rnd1 = std::mt19937(std::random_device{}());
// Good random seed, default engine
auto rnd2 = std::default_random_engine(std::random_device{}());
// like rnd1, but force distribution to int32_t range
auto rnd3 = std::bind(std::uniform_int_distribution<int32_t>{}, std::mt19937(std::random_device{}()));
// like rnd3, but force distribution across negative numbers as well
auto rnd4 = std::bind(std::uniform_int_distribution<int32_t>{std::numeric_limits<int32_t>::min(),std::numeric_limits<int32_t>::max()}, std::mt19937(std::random_device{}()));
然后我运行了一些测试,看看默认值是什么样子的:
#include <random>
#include <functional>
#include <limits>
#include <iostream>
template<class Func>
void print_min_mean_max(Func f) {
typedef decltype(f()) ret_t;
ret_t min = std::numeric_limits<ret_t>::max(), max = std::numeric_limits<ret_t>::min();
uint64_t total = 0, count = 10000000;
for (uint64_t i = 0; i < count; ++i) {
auto res = f();
min = std::min(min,res);
max = std::max(max,res);
total += res;
}
std::cout << "min: " << min << " mean: " << (total/count) << " max: " << max << std::endl;
}
int main() {
auto rnd1 = std::mt19937(std::random_device{}());
auto rnd2 = std::default_random_engine(std::random_device{}());
auto rnd3 = std::bind(std::uniform_int_distribution<int32_t>{}, std::mt19937(std::random_device{}()));
auto rnd4 = std::bind(std::uniform_int_distribution<int32_t>{std::numeric_limits<int32_t>::min(),std::numeric_limits<int32_t>::max()}, std::mt19937(std::random_device{}()));
print_min_mean_max(rnd1);
print_min_mean_max(rnd2);
print_min_mean_max(rnd3);
print_min_mean_max(rnd4);
}
产生输出:
min: 234 mean: 2147328297 max: 4294966759
min: 349 mean: 1073305503 max: 2147483423
min: 601 mean: 1073779123 max: 2147483022
min: -2147481965 mean: 178496 max: 2147482978
所以我们可以看到,mt19937和default_random_engine有一个不同的默认范围,所以建议使用uniform_int_distribution。
另外,默认的uniform_int_distribution是[0,max_int](非负),即使使用有符号整数类型也是如此。如果想要全量程,必须显式提供量程。
如果您现有的代码在新标准之前是合适的,那么它将继续适用。新的随机数生成器被添加到需要更高质量的伪随机性的应用程序中,例如随机模拟。
我在我的项目中使用以下代码。'engine'和'distribution'可以是库提供的其中一个。
#include <random>
#include <functional>
#include <iostream>
...
std::uniform_int_distribution<unsigned int> unif;
std::random_device rd;
std::mt19937 engine(rd());
std::function<unsigned int()> rnd = std::bind(unif, engine);
std::cout << rnd() << 'n';
给你。范围内的随机双精度:
// For ints
// replace _real_ with _int_,
// <double> with <int> and use integer constants
#include <random>
#include <iostream>
#include <ctime>
#include <algorithm>
#include <iterator>
int main()
{
std::default_random_engine rng(std::random_device{}());
std::uniform_real_distribution<double> dist(-100, 100); //(min, max)
//get one
const double random_num = dist(rng);
//or..
//print 10 of them, for fun.
std::generate_n(
std::ostream_iterator<double>(std::cout, "n"),
10,
[&]{ return dist(rng);} );
return 0;
}
随机数生成是一个难题。没有真正随机的方法来做到这一点。如果你只是为了创造一个游戏环境而创造随机性,那么你的方法便是可行的。Rand()有几个缺点。
如果你需要随机生成加密密钥,那么你是s.o.l。在这种情况下,最好的方法是去操作系统,它通常有机制。在POSIX上,它是random()(或者从/dev/random读取,如果你愿意的话)。在Windows上,您可以使用CryptoAPI:
https://www.securecoding.cert.org/confluence/display/seccode/MSC30-C。+ +不+使用+ +兰特% 29 +功能+ 28% +生成+伪随机+数字
您可以使用RC4生成随机字节。这可能有你想要的属性。它是快速和相当简单的实现。当种子已知时,序列在所有实现中都是可重复的,而当种子未知时,序列是完全不可预测的。http://en.wikipedia.org/wiki/RC4
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 整数不会重复超过随机数
- 使用CMake检测支持的C++标准
- 如何理解C++标准N3337中的expr.const.cast子句8
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 编译标准库类型
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- if数组上的随机数
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 在将数字随机生成为数组期间从内存输出随机数的数组
- 铸造标准::有没有回到原来的类型
- 标准 N3337 5.2.10 第 7 条中的C++"类型"是什么意思?
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 标准库类型的赋值运算符的引用限定符
- 半随机数生成C++
- 使用给定种子生成的随机数序列是否保证在标准版本中相同?
- 在 c++ 中创建具有指数分布的随机数(可视化标准)
- C++11 标准是否保证跨实现的同一种子具有相同的随机数?
- C++中基于种子的标准可移植伪随机数生成器
- 如何使用c++ 11标准库生成随机数