@zhengyuhong
2015-06-09T01:40:29.000000Z
字数 6297
阅读 1489
C++11 STL
This library allows to produce random numbers using combinations of generators and distributions
Generators: Objects that generate uniformly distributed numbers.
Distributions: Objects that transform sequences of numbers generated by a generator into sequences of numbers that follow a specific random variable distribution, such as uniform, Normal or Binomial.
engines . 负责生成原始随机数
distributions . 迫使生成的随机数在统计上满足指定的概率分布
template <class UIntType, UIntType a, UIntType c, UIntType m>class linear_congruential_engine;
线性同余法:This is the simplest generator engine in the standard library. Its state is a single integer value, with the following transition algorithm:
typedef linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647> minstd_rand;typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647> minstd_rand0;result_type operator()();//Generate random numberstatic constexpr result_type min();static constexpr result_type max();void seed (result_type val = default_seed);template <class Sseq>void seed (Sseq& q);//Re-initializes the internal state value
// linear_congruential_engine constructor#include <iostream>#include <chrono>#include <random>int main (){// obtain a seed from the system clock:unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();std::minstd_rand0 g0 (seed);std::minstd_rand g (seed);for(int i=0; i < 10; ++i) {std::cout << "A time seed for g0 produced: " << g0() << std::endl;std::cout << "A time seed for g produced: " << g() << std::endl;}return 0;}
template <class UIntType, size_t w, size_t n, size_t m, size_t r,UIntType a, size_t u, UIntType d, size_t s,UIntType b, size_t t,UIntType c, size_t l, UIntType f>class mersenne_twister_engine;
梅森旋转法.A pseudo-random number generator engine that produces unsigned integer numbers in the closed interval [0,2w-1].
The algorithm used by this engine is optimized to compute large series of numbers (such as in Monte Carlo experiments) with an almost uniform distribution in the range.
typedef mt19937 default_random_engine;
mt19937 mt19937_64 is Template instantiations of mersenne_twister_engine
成员函数.max,min,operator(),seed,等均与linear_congruential_engine一致
标准库提供了一个非确定性随机数生成设备.在Linux的实现中,是读取/dev/urandom设备;Windows的实现居然是用rand_s。random_device提供()操作符,用来返回一个min()到max()之间的一个数字.如果是Linux(Unix Like或者Unix)下,都可以使用这个来产生高质量的随机数,可以理解为真随机数.
#include <iostream>#include <random>int main (){std::random_device rd;std::cout << "default random_device characteristics:" << std::endl;std::cout << "minimum: " << rd.min() << std::endl;std::cout << "maximum: " << rd.max() << std::endl;std::cout << "entropy: " << rd.entropy() << std::endl;std::cout << "a random number: " << rd() << std::endl;return 0;}
seed_seq();template<class T>seed_seq (initializer_list<T> il);template<class InputIterator>seed_seq (InputIterator first, InputIterator last);
#include <iostream>#include <random>#include <string>#include <array>int main (){std::seed_seq seed1;std::seed_seq seed2 = {102,406,7892};std::string foo = "Seeding a RNG";std::seed_seq seed3 (foo.begin(),foo.end());std::cout << "generating a sequence of 5 elements:" << std::endl;std::array<unsigned,5> sequence;seed3.generate(sequence.begin(),sequence.end());for (unsigned x:sequence) {std::cout << x << std::endl;}return 0;}
template <class RandomAccessIterator>void generate (RandomAccessIterator first, RandomAccesIterator last);
Generate sequence
Fills the supplied sequence with a sequence 32-bit values that can be used to seed a pseudo-random number generator engine.
template <class IntType = int> class uniform_int_distribution;
explicit uniform_int_distribution ( result_type a = 0,result_type b = numeric_limits<result_type>::max() );explicit uniform_int_distribution ( const param_type& parm );
template <class RealType = double> class uniform_real_distribution;
explicit uniform_real_distribution ( result_type a = 0.0, result_type b = 1.0 );explicit uniform_real_distribution ( const param_type& parm );
template <class RealType = double> class normal_distribution;
explicit normal_distribution ( result_type mean = 0.0, result_type stddev = 1.0 );explicit normal_distribution ( const param_type& parm );
template <class IntType = int> class discrete_distribution;
discrete_distribution();template <class InputIterator>discrete_distribution (InputIterator first, InputIterator last);discrete_distribution (initializer_list<double> il);template <class UnaryOperation>discrete_distribution (size_t nw, double xmin, double xmax, UnaryOperation fw);explicit discrete_distribution (const param_type& parm);
example
#include <iostream>#include <chrono>#include <random>#include <functional>#include <array>int main(){// construct a trivial random generator engine from a time-based seed:unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();std::default_random_engine generator (seed);std::array<double,4> init = {1.0,2.0,3.0,4.0};std::discrete_distribution<int> first;std::discrete_distribution<int> second (init.begin(),init.end());std::discrete_distribution<int> third {0.1,0.2,0.3,0.4};// display probabilities:std::cout << "displaying probabilities:";std::cout << std::endl << "first : ";for (double x:first.probabilities()) {std::cout << x << " ";}std::cout << std::endl << "second: ";for (double x:second.probabilities()) {std::cout << x << " ";}std::cout << std::endl << "third : ";for (double x:third.probabilities()) {std::cout << x << " ";}return 0;}
以上的分布查看C++参考即可看到很简单的API接口,至于由分布产生随机数更加统一使用operator()的方法即可
template<class URNG>result_type operator()(URNG& g);template<class URNG>result_type operator()(URNG& g, const param_type& parm);
example
标准把随机数抽象成随机数引擎和分布两部分.引擎用来产生随机数,分布产生特定分布的随机数(比如平均分布,正太分布等).
标准提供三种常用的引擎:linear\_congruential\_engine,mersenne\_twister\_engine和subtract\_with\_carry\_engine.第一种是线性同余算法,第二种是梅森旋转算法,第三种带进位的线性同余算法.第一种是最常用的,而且速度也是非常快的; 第二种号称是最好的伪随机数生成器;第三种没用过....
随机数引擎接受一个整形参数当作种子,不提供的话,会使用默认值. 推荐使用random\_device来产生一个随机数当作种子.(windows下爱咋整咋整,谁叫windows的random\_device是调用rand_s)
#include <iostream>#include <chrono>#include <random>int main(){// construct a trivial random generator engine from a time-based seed:unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();std::default_random_engine generator (seed);std::uniform_real_distribution<double> distribution (0.0,100.0);std::cout << "some random numbers between 0.0 and 100.0: " << std::endl;for (int i=0; i<10; ++i){std::cout << distribution(generator) << std::endl;}return 0;}