At the core of any pseudorandom number generation software is a routine for generating uniformly distributed random integers.
In C++ TR1 you have your choice of several core generators that it calls “engines.” The following four engine classes are supported in the Visual Studio 2008 feature pack
(微软已经发布了Visual Studio 2008的Services Pack 1,它包含了此前发布的feature pack,以及完整的TR1支持,后来又发布了一个修正:VC 2008 SP1: Problems with STL/TR1 after installing VS2008 SP1,关于:VC9 SP1 Hotfix For The vector<function<FT>> Crash,关于文档:微软TR1文档).
- linear_congruential uses a recurrence of the form x(i) = (A * x(i-1) + C) mod M
- mersenne_twister implements the famous Mersenne Twister algorithm
- subtract_with_carry uses a recurrence of the form x(i) = (x(i - R) - x(i - S) - cy(i - 1)) mod M in integer arithmetic
- subract_with_carry_01 uses a recurrence of the form x(i) = (x(i - R) - x(i - S) - cy(i - 1)) mod 1 in floating point arithmetic
Each engine has a seed() method that accepts an unsigned long argument to specify the random number generation seed. It is also possible to set the seed in more detail using template parameters unique to each engine.
微软的C++ TR1可以生成以下分布的随机数:
Generates a Bernoulli distribution. |
Generates a binomial distribution. |
Generates an exponential distribution. |
Generates a gamma distribution. |
Generates a geometric distribution. |
Generates a normal distribution. |
Generates a Poisson distribution. |
Generates a uniform integer distribution. |
Generates a uniform floating-point distribution. |
试验一:在VS2008中先建一空的VC++项目文件,然后添加新建项cpp文件如下:
#include <random>
#include <iostream>
void main(){
std::tr1::mt19937 eng; // a core engine class:Mersenne Twister generator
std::tr1::normal_distribution<double> dist;
std::tr1::uniform_int<int> unif(1, 52);
for (int i = 0; i < 10; ++i) //产生正态分布的10个随机数
std::cout << dist(eng)<<std::endl;
for(int i = 0; i < 5; ++i) //产生均匀分布的在1到52之间的五个整数随机数
std::cout << unif(eng) << std::endl;
}
在循环中,每循环一次,就调用mt19937 eng一次,产生一个随机数输出。
试验二:关于种子seed
#include <random>
#include <iostream>
#include <time.h>
void main(){
std::tr1::mt19937 eng; // a core engine class:Mersenne Twister generator
std::tr1::normal_distribution<double> dist;
std::tr1::uniform_int<int> unif(1, 52);
eng.seed((unsigned int)time(NULL)); // reseed base engine 设置种子用#include <time.h>, 不能用#include <time>
for (int i = 0; i < 10; ++i) //产生正态分布的10个随机数
std::cout << dist(eng)<<std::endl;
//eng.seed(); // reseed base engine
for(int i = 0; i < 5; ++i) //产生均匀分布的在1到52之间的五个整数随机数
std::cout << unif(eng) << std::endl;
}
试验三:随机数写入文件
#include <random>
#include <iostream>
#include <fstream>
#include <time.h>
using namespace std;
using namespace std::tr1;
void main()
{
mt19937 eng; // a core engine class:Mersenne Twister generator
normal_distribution<double> dist;
uniform_int<int> unif(1, 52);
eng.seed((unsigned int)time(NULL)); // 设置种子用#include <time.h>, 不能用#include <time>
for (int i = 0; i < 10; ++i) //产生正态分布的10个随机数
cout << dist(eng)<<endl;
ofstream fileout("fileout.dat");
for(int i = 0; i < 5; ++i) //产生均匀分布的在1到52之间的五个整数随机数
fileout << unif(eng)<< endl;
fileout.close();
}
试验四:第三方"Mersenne Twister"随机数生成程序使用试验(程序来源:Agner Fog http://www.agner.org/random/)
// 使用说明:从网站下载压缩包,http://www.agner.org/random/randomc.zip
// 展开后,将其中的randomc.h头文件及mersenne.cpp文件Copy到项目文件夹,
// 并将它们加入到项目中,其中包括"Mersenne Twister"的实现
#include <iostream>
#include <time.h>
#include "randomc.h" // define classes for random number generators
using namespace std;
void main()
{
int seed = (int)time(0); // random seed
// choose one of the random number generators:
CRandomMersenne RanGen(seed); // make instance of random number generator
cout<<"\n\nRandom integers in interval from 0 to 99:\n";
for (int i = 0; i < 40; i++) {
int ir = RanGen.IRandom(0,99);
cout<<ir<<" ";
}
cout <<endl;
cout<<"\n\n\n\nRandom floating point numbers in interval from 0 to 1:\n";
for (int i = 0; i < 40; i++) {
float fr = RanGen.Random();
cout<<fr<<" ";
}
cout <<endl;
}
试验五:第三方"Mother-Of-All"随机数生成程序使用试验(程序来源:Agner Fog http://www.agner.org/random/)
// 使用说明:从网站下载压缩包,http://www.agner.org/random/randomc.zip
// 展开后,将其中的randomc.h头文件及mother.cpp文件Copy到项目文件夹,
// 并将它们加入到项目中,其中包括"Mother-Of-All" generator invented by George Marsaglia 的实现
#include <iostream>
#include <time.h>
#include "randomc.h" // define classes for random number generators
using namespace std;
void main()
{
int seed = (int)time(0); // random seed
// choose one of the random number generators:
CRandomMother RanGen(seed); // make instance of random number generator
cout<<"\n\nRandom integers in interval from 0 to 99:\n";
for (int i = 0; i < 40; i++) {
int ir = RanGen.IRandom(0,99);
cout<<ir<<" ";
}
cout <<endl;
cout<<"\n\n\n\nRandom floating point numbers in interval from 0 to 1:\n";
for (int i = 0; i < 40; i++) {
float fr = RanGen.Random();
cout<<fr<<" ";
}
cout <<endl;
}
试验六:第三方"SFMT"随机数生成程序使用试验(程序来源:Agner Fog http://www.agner.org/random/)
重要提示:在编译前,可以修改头文件sfmt.h中的#define MEXP以及下面相应的宏代码:Choose one of the possible Mersenne exponents. Higher values give longer cycle length and use more memory。SFMT利用了SSE2指令,速度最快,但只适合intel系列的部分芯片。
// 使用说明:从网站下载压缩包,http://www.agner.org/random/randomc.zip
// 展开后,将其中的头文件及sfmt.cpp文件Copy到项目文件夹,
// 并将它们加入到项目中,其中包括"SFMT" 的实现
#include <iostream>
#include <time.h>
#include "sfmt.h" // define classes for random number generators
using namespace std;
void main()
{
int seed = (int)time(0); // random seed
// choose one of the random number generators:
CRandomSFMT1 RanGen(seed); //注意可以是CRandomSFMT,是CRandomSFMT0,或CRandomSFMT1
cout<<"\n\nRandom integers in interval from 0 to 99:\n";
for (int i = 0; i < 40; i++) {
int ir = RanGen.IRandomX(0,99);
cout<<ir<<" ";
}
cout <<endl;
cout<<"\n\n\n\nRandom floating point numbers in interval from 0 to 1:\n";
for (int i = 0; i < 40; i++) {
float fr = RanGen.Random();
cout<<fr<<" ";
}
cout <<endl;
}