c++生成随机数
2015-09-18 16:57
489 查看
一.获取均匀分布的随机数
经典方法:
[code]#include<stdlib.h> // 产生随机数,范围在0~RAND_MAX之间,RAND_MAX在stdlib中,其值为2147483647 rand();
rand的机制是根据一个随机数种子(通常是一个整数值,如果没有设置,则为默认值)来生成一系列指定顺序的随机数,如果种子相同,那么一系列的随机数也是相同的。所以如果你
rand();后再
rand();就会得到一样的。
原理:
Srand ( );和
Rand( );函数。它本质上是利用线性同余法,
y=ax+b(mod m);其中a,b,m都是常数。因此rand的产生决定于x,x被称为Seed。
可以通过srand()来设置随机数种子。较为普遍的做法是将随机数种子设为time()的时间函数,这样就能根据当前的时间来设置随机数种子,不会存在重复的问题。
time()包含在time.h中,返回从一个特定时刻到现在经过了多少秒,它接受单个指针参数,用于指向写入时间的数据结构,若为空,则简单的返回时间。用于产生随机数种子通常用
time(0);
如果你要获取一定范围内的随机数,
rand()%MAX,MAX为你设置的范围。可以
#define random(x) (rand()%x)来简化使用过程,使用时就直接
rand(max);就好了
c++11中的新标准:
[code]#include<random>// 随机数库:由引擎类和分布类组成 std::default_random_engine e;// 随机数引擎,生成随机无符号数 e();// 取出队列头的随机数
和rand()函数类似,也是依靠随机数种子,种子可以在初始化时指定
std::default_random_engine e(seed);(seed为整型值);也可以调用seed()成员函数指定
e.seed(seed);
标准库定义了多个随机数引擎类,区别在于性能和随机性质量不同,每个编译器都会指定其中一个作为default_random_engine类型。此类型一般具有最常用的特性。有兴趣的请自行了解“标准库随机数引擎”。
随机数引擎操作 | 介绍 |
---|---|
Engine e; | 默认构造函数 |
Engine e(s) | 使用整型值s为种子 |
e.seed(s) | 使用种子s重置引擎的状态 |
e.min() | 此引擎可生成的最小值 |
e.max() | 此引擎可生成的最大值 |
Engine::result_type | 此引擎生成的unsigned整型类型 |
e.discard(u) | 将引擎推进u步;u的类型为unsigned long long |
二.获取任意分布的随机数
经典:
分布得靠自己去处理example
指数分布:[code]double cls_random::randomExponential( double lambda) { double pV = 0.0; while(true) { pV = (double)rand()/(double)RAND_MAX; if (pV != 1) { break; } } pV = (-1.0/lambda)*log(1-pV); return pV; }
期望:E=\lambda^{-1}\
方差:V=\lambda^{-2}\
此方法的参考网址
c++11新标准:
标准库定义了一系列的分布类型,分布就是在随机数引擎产生的随机数的基础上进行过滤调整,以符合一定的规律,下面以正态分布的使用为例example
[code]#include <iostream> #include <random> #include <string> using namespace std; int main() { default_random_engine e;// 生成随机整数 normal_distribution<double> n(4,1.5);// 均值4,标准差1.5 int vals[9]; for(size_t i = 0;i != 200;i++) { // n(e)得到正态分布的double值 // lround将double舍入到最近的整型值 int v = lround(n(e)); if(v<9)//如果结果在范围内 { ++vals[v];// 统计每个数出现了多少次 } } for(int j = 0;j != 9;j++ ) { // 打印每个数出现的频率 cout<< j << ":" << string(vals[j], '*') <<endl; } }
输出结果:
0:*1:[b]*[/b]
2:[b]********[/b]
3:[b]**********************************[/b]
4:[b]*********************************************[/b]
5:[b]**********************[/b]
6:[b]********************[/b]
7:*
8:*
附录
随机数分布
分布类 | 介绍 |
---|---|
均匀分布: | |
uniform_int_distribution<IntT> u(m,n) | 均匀分布的模板类,m为生成的最小值,n最大,生成int |
uniform_real_distrubution<RealT> u(x,y) | 同上,生成double |
伯努利分布: | |
bernoulli_distribution b(p) | 伯努利分布,以给定概率p生成true,默认0.5 |
binomial_distribution<IntT> b(t,p) | 按采样大小为整型值t,概率为p生成的;t默认1,p默认0.5 |
geometric_distribution<IntT> g(p) | 每次实验成功的概率为p |
negative_binomial_distribution<IntT>nb(k,p) | k(整型值)次实验成功的概率为p;k默认为1,p默认0.5 |
泊松分布: | |
poisson_distribution<IntT>p(x) | 均值为double值x的泊松分布 |
exponential_distribution<RealT> e(lam) | 指数分布,参数lambda通过腹地安置lam给出,lan默认为1.0 |
gamma_distribution<RealT> e(a,b) | alpha(形状参数)为a,beta(尺度参数)为b;默认值均为1.0 |
weibull_distribution<RealT> w(a,b) | 形状参数为a,尺度参数为b;默认1.0 |
extreme_value__distribution<RealT>e(a,b) | a的默认值为0.0,b的为1.0 |
正态分布: | |
normal_distribution<RealT>n(m,s) | 均值为m,标准差为s;m默认为0,s默认1.0 |
lognarmal_distribution<RealT> ln(m,s) | 均值为m,标准差为s;m的默认值为0.0,s的默认值为1.0 |
chi_squared_distribution(RealT)c(x) | 自由度为x,默认值为1.0 |
cauchy_distribution<RealT>c(a,b) | 位置参数a和尺度参数b的默认值为0.0和1.0 |
fisher_f_distribution<RealT>f(m,n) | 自由度为m和n,默认值均为1 |
student_t_distribution<RealT>s(n) | 自由度为n;n默认为1 |
抽样分布: | |
discrete_distribution<IntT>d(i,j) | 见下 |
discrete_distribution<IntT>d{ il } | i和j是一个权重序列的输入迭代器,il是一个权重的花括号列表。权重必须能转换为double |
piecewise_constant_distribution<RealT> pc(b,e,w) | b,e,w是输入迭代器 |
piecewise_linear_distribution<RealT> pl(b,e,w) | b,e,w是输入迭代器 |
随机数引擎
相关文章推荐
- 【C++】智能指针
- C++STL 迭代器
- 用 C++实现的简单物流信息存储
- Effective C++——operator =
- C语言改变循环的状态
- C语言中动态分配数组
- C++中传递数组参数的几种用法和注意点
- swig C#链接c++ dll
- Effective C++——条款45(第7章)
- c++ 抽象概念,内存格局,浅拷贝,深拷贝,临时对象,无名对象
- C++中不能被定义为虚函数的函数
- 详解C++编程中的单目运算符重载与双目运算符重载
- c/c++复习日记 1.不带缓存的I/O和标准I/O
- C++运算符重载规则详解
- 矩阵乘法算法
- 简介C++编程中的运算符重载
- C++ Primer Plus 第6版 中文版 第7章编程练习
- C++读入输出优化
- 【C++】vector、list、map、set
- C++:类和对象