admin管理员组文章数量:1794759
C++11中随机数生成器(random)
目录
- 1 随机数生成器的分类
- 2 随机数据引擎
- 2.1 线性同余法引擎
- 2.2 梅森旋转法引擎
- 2.3 滞后Fibonacci引擎
- 2.4 非确定随机生成器
- 2.5 默认随机数引擎
- 3 随机数适配器
- 3.1 std::discard_block_engine
- 3.2 std::independent_bits_engine
- 3.3 std::shuffle_order_engine
- 4 随机数分布类
- 4.1 均匀分布:
- 4.2 伯努利类型分布:(仅有yes/no两种结果,概率一个p,一个1-p)
- 4.3 泊松分布:
- 4.4 正态分布相关:
- 4.5 分段分布相关:
- 5 小工具
- 5.1 generate_canonical
- 5.2 seed_seq
- 6 示例
- 7 参考
一般随机数生成器和随机数生成类配合使用,去生成随机数据。
2 随机数据引擎 2.1 线性同余法引擎类的声明,由于实现了operator(),所以他是一个仿函数类。
template< class UIntType, // The result type generated by the generator. The effect is undefined if this is not one of unsigned short, unsigned int, unsigned long, or unsigned long long UIntType a, // the multiplier term UIntType c, // the increment term UIntType m // the modulus term > class linear_congruential_engine;random库贴心的帮我们typedef了两个类型,防止我们不知道怎么设置参数 😃
// Discovered in 1969 by Lewis, Goodman and Miller, adopted as "Minimal standard" in 1988 by Park and Miller using minstd_rand0 = std::linear_congruential_engine<std::uint_fast32_t, 16807, 0, 2147483647> // Newer "Minimum standard", recommended by Park, Miller, and Stockmeyer in 1993 using minstd_rand = std::linear_congruential_engine<std::uint_fast32_t, 48271, 0, 2147483647> 2.2 梅森旋转法引擎类的声明,同样也是仿函数类
template< class UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f > class mersenne_twister_engine;typedef的类型
// 32-bit Mersenne Twister by Matsumoto and Nishimura, 1998 using mt19937 = std::mersenne_twister_engine<std::uint_fast32_t, 32, 624, 397, 31, 0x9908b0df, 11, 0xffffffff, 7, 0x9d2c5680, 15, 0xefc60000, 18, 1812433253>; // 64-bit Mersenne Twister by Matsumoto and Nishimura, 2000 using mt19937_64 = std::mersenne_twister_engine<std::uint_fast64_t, 64, 312, 156, 31, 0xb5026f5aa96619e9, 29, 0x5555555555555555, 17, 0x71d67fffeda60000, 37, 0xfff7eee000000000, 43, 6364136223846793005>; 2.3 滞后Fibonacci引擎类的声明,也是反函数类
template< class UIntType, std::size_t w, std::size_t s, std::size_t r > class subtract_with_carry_engine;typedef的类型
using ranlux24_base = std::subtract_with_carry_engine<std::uint_fast32_t, 24, 10, 24> using ranlux48_base = std::subtract_with_carry_engine<std::uint_fast64_t, 48, 5, 12> 2.4 非确定随机生成器类的声明
class random_device;它并不是由某一个数学算法得到的随机序列,而是通过读取文件,读什么文件看具体的实现(Linux可以通过读取/dev/random文件来获取)。文件的内容是随机的,因为文件内容是计算机系统的熵(熵指的是一个系统的混乱程度)。也是当前系统的环境噪声,系统噪音可以通过很多参数来评估,如内存的使用,文件的使用量,不同类型的进程数量等等。Linux的熵来自键盘计时、鼠标移动等。 在没有非确定源(如硬件设备)时他会产生伪随机数,此时每一个random_device的对象会产生相同的随机数序列
例子:
#include <iostream> #include <random> void demo(std::random_device&& rd) { for(int n = 0; n != 10; ++n) { std::cout << rd() << ' '; } std::cout << '\\n'; } int main() { // Note: How the supplied token is handled is implementation-defined! // Default token for random_device is usually /dev/urandom on Linux demo(std::random_device{}); // Request /dev/random, blocks when entropy is empty // Works on libstdc++, ignored in msvc++, might throw on libc++ (as of Nov 2022) demo(std::random_device{"/dev/random"}); // Request non-blocking /dev/urandom, ensures that RDRAND is not used // Works on libstdc++ and libc++, ignored in msvc++ (as of Nov 2022) demo(std::random_device{"/dev/urandom"}); // Request "hw", will use hardware-based random generation like rdrand // Works on libstdc++, ignored in msvc++, throws on libc++ (as of Nov 2022) demo(std::random_device{"hw"}); } 2.5 默认随机数引擎 std::default_random_engine; // 由编译器定义 3 随机数适配器随机数适配器的作用就是对上述引擎产生的随机序列进行修饰和适配。
3.1 std::discard_block_engine它丢弃由基本引擎产生的一定数量的数据。从每一块大小P由基本引擎生成的适配器只保留R数字,丢弃剩下的。
类声明
template< class Engine, std::size_t P, std::size_t R > class discard_block_engine;typedef的类型
// 24-bit RANLUX generator by Martin Lüscher and Fred James, 1994 using ranlux24 = std::discard_block_engine<std::ranlux24_base, 223, 23>; // 48-bit RANLUX generator by Martin Lüscher and Fred James, 1994 using ranlux48 = td::discard_block_engine<std::ranlux48_base, 389, 11>; 3.2 std::independent_bits_engineindependent_bits_engine是一个随机数引擎适配器,它产生与包装引擎不同位数的随机数。
类的声明
template< class Engine, std::size_t W, class UIntType > class independent_bits_engine; 3.3 std::shuffle_order_engine他会对随机数引擎产生的序列随机重排,并将其保存在大小为k的表中,当有请求是从中选择一个返回,之后使用随机数引擎产生一个随机数填补这个位置。
类的声明
template< class Engine, std::size_t K > class shuffle_order_engine;typedef的类型
using knuth_b = std::shuffle_order_engine<std::minstd_rand0, 256>; 4 随机数分布类随机数分布类可以将随机数引擎产生的随机数转成特定分布输出,如整型均匀分布(std::uniform_int_distribution):
类的声明
template< class IntType = int > class uniform_int_distribution;例子
#include <iostream> #include <random> int main() { std::random_device rd; // Will be used to obtain a seed for the random number engine std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd() std::uniform_int_distribution<> distrib(1, 6); // Use distrib to transform the random unsigned int // generated by gen into an int in [1, 6] for (int n = 0; n != 10; ++n) std::cout << distrib(gen) << ' '; std::cout << '\\n'; } 4.1 均匀分布:- uniform_int_distribution 整数均匀分布
- uniform_real_distribution 浮点数均匀分布
- bernoulli_distribution 伯努利分布
- binomial_distribution 二项分布
- geometry_distribution 几何分布
- negative_biomial_distribution 负二项分布
- poisson_distribution 泊松分布
- exponential_distribution指数分布
- gamma_distribution 伽马分布
- weibull_distribution 威布尔分布
- extreme_value_distribution 极值分布
- normal_distribution 正态分布
- lognormal_distribution 对数正态分布
- chi_squared_distribution 卡方分布
- cauchy_distribution 柯西分布
- fisher_f_distribution 费歇尔F分布
- student_t_distribution t分布
- discrete_distribution离散分布
- piecewise_constant_distribution分段常数分布
- piecewise_linear_distribution分段线性分布
std::generate_canonical 可以产生[0,1)范围内随机浮点数
类的声明
template< class RealType, std::size_t Bits, class Generator > RealType generate_canonical( Generator& g );例子
#include <random> #include <iostream> int main() { std::random_device rd; std::mt19937 gen(rd()); for(int n=0; n<10; ++n) { std::cout << std::generate_canonical<double, 10>(gen) << ' '; } } 5.2 seed_seq他可以产生无符号整型范围内的值序列 类的声明
class seed_seq;例子
#include <random> #include <cstdint> #include <iostream> int main() { std::seed_seq seq{1,2,3,4,5}; std::vector<std::uint32_t> seeds(10); seq.generate(seeds.begin(), seeds.end()); for (std::uint32_t n : seeds) { std::cout << n << '\\n'; } }输出
4204997637 4246533866 1856049002 1129615051 690460811 1075771511 46783058 3904109078 1534123438 1495905678 6 示例 #include <cmath> #include <iomanip> #include <iostream> #include <map> #include <random> #include <string> int main() { // Seed with a real random value, if available std::random_device r; // Choose a random mean between 1 and 6 std::default_random_engine e1(r()); std::uniform_int_distribution<int> uniform_dist(1, 6); int mean = uniform_dist(e1); std::cout << "Randomly-chosen mean: " << mean << '\\n'; // Generate a normal distribution around that mean std::seed_seq seed2{r(), r(), r(), r(), r(), r(), r(), r()}; std::mt19937 e2(seed2); std::normal_distribution<> normal_dist(mean, 2); std::map<int, int> hist; for (int n = 0; n != 10000; ++n) ++hist[std::round(normal_dist(e2))]; std::cout << "Normal distribution around " << mean << ":\\n" << std::fixed << std::setprecision(1); for (auto [x, y] : hist) std::cout << std::setw(2) << x << ' ' << std::string(y / 200, '*') << '\\n'; } 7 参考版权声明:本文标题:C++11中随机数生成器(random) 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1686992593a126361.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论