源于SJ加分题的发红包,想到如何生成制定分布的随机数。
当时就想到红包的值应该是以红包的平均值为峰值的正态的分布。(后来想想应该是偏态分布)这个分布的平均值是红包的平均值。实际上,那个函数的具体实现方法应该是也不是这么简单,我还没找到合适的方法。
前几天看机器学习的时候看到一个Gamma分布(看这个图形的样子的好像是偏态分布。就去学习了一番。
平均分布
过于简单,不再赘述
正态分布
最广为流传的方式应该就是Box-Muller的变换了。
,
是随机分布的
内的随机数
![Rendered by QuickLaTeX.com \[U_1=Rand()\quad U_2=Rand()\]](http://yyjxx2010xyu.top/wp-content/ql-cache/quicklatex.com-4446157fb5479fc18b3f0f47646ccd5e_l3.png)
![Rendered by QuickLaTeX.com \[Z=R*\cos(\theta)\]](http://yyjxx2010xyu.top/wp-content/ql-cache/quicklatex.com-c734e5bb2b5756dcc5a9541e96c438d4_l3.png)
![Rendered by QuickLaTeX.com \[R=\sqrt{-2*\ln(U_2)}\]](http://yyjxx2010xyu.top/wp-content/ql-cache/quicklatex.com-0cc3f36eb9d92769f203d5c6834c056f_l3.png)
![Rendered by QuickLaTeX.com \[\theta=2*\pi*U_1\]](http://yyjxx2010xyu.top/wp-content/ql-cache/quicklatex.com-df417d4e23db6207d6f4da8ca005cbd4_l3.png)
这样的
就是符合正态分布的随机数了。
Gamma分布
发现网上也没什么资料,不过C++11提供了很多现成的库来生成不同分布的随机数。这是C++PLUSPLUS的URL。
有Gamma分布,Binomial分布,还有指数分布,大概有十多个。
// gamma_distribution
#include <iostream>
#include <random>
int main()
{
const int nrolls=10000; // number of experiments
const int nstars=100; // maximum number of stars to distribute
std::default_random_engine generator;
std::gamma_distribution<double> distribution(2.0,2.0);
int p[10]={};
for (int i=0; i<nrolls; ++i) {
double number = distribution(generator);
if (number<10) ++p[int(number)];
}
std::cout << "gamma_distribution (2.0,2.0):" << std::endl;
for (int i=0; i<10; ++i) {
std::cout << i << "-" << (i+1) << ": ";
std::cout << std::string(p[i]*nstars/nrolls,'*') << std::endl;
}
return 0;
}
Possible output:
gamma_distribution (2.0,2.0):
0-1: *********
1-2: *****************
2-3: ******************
3-4: **************
4-5: ************
5-6: *********
6-7: *****
7-8: ****
8-9: ***
9-10: **
|
UPDATE(2019/7/31):
在知乎上看到的TESTU01,可以用来检验随机数生成的随机性(Random Number Generator, RNG),有官方文档用来证明验证的方式和验证函数的使用。