[关闭]
@zhengyuhong 2015-06-09T01:40:29.000000Z 字数 6297 阅读 1489

random

C++11 STL


random

  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 . 迫使生成的随机数在统计上满足指定的概率分布

linear_congruential_engine

  1. template <class UIntType, UIntType a, UIntType c, UIntType m>
  2. 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:
x=(ax+c) mod m

  1. typedef linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647> minstd_rand;
  2. typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647> minstd_rand0;
  3. result_type operator()();
  4. //Generate random number
  5. static constexpr result_type min();
  6. static constexpr result_type max();
  7. void seed (result_type val = default_seed);
  8. template <class Sseq>
  9. void seed (Sseq& q);
  10. //Re-initializes the internal state value
  1. // linear_congruential_engine constructor
  2. #include <iostream>
  3. #include <chrono>
  4. #include <random>
  5. int main ()
  6. {
  7. // obtain a seed from the system clock:
  8. unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
  9. std::minstd_rand0 g0 (seed);
  10. std::minstd_rand g (seed);
  11. for(int i=0; i < 10; ++i) {
  12. std::cout << "A time seed for g0 produced: " << g0() << std::endl;
  13. std::cout << "A time seed for g produced: " << g() << std::endl;
  14. }
  15. return 0;
  16. }

mersenne_twister_engine

  1. template <class UIntType, size_t w, size_t n, size_t m, size_t r,
  2. UIntType a, size_t u, UIntType d, size_t s,
  3. UIntType b, size_t t,
  4. UIntType c, size_t l, UIntType f>
  5. 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.

default_random_engine

  1. typedef mt19937 default_random_engine;

  mt19937 mt19937_64 is Template instantiations of mersenne_twister_engine
  成员函数.max,min,operator(),seed,等均与linear_congruential_engine一致

random_device

  标准库提供了一个非确定性随机数生成设备.在Linux的实现中,是读取/dev/urandom设备;Windows的实现居然是用rand_s。random_device提供()操作符,用来返回一个min()到max()之间的一个数字.如果是Linux(Unix Like或者Unix)下,都可以使用这个来产生高质量的随机数,可以理解为真随机数.

  1. #include <iostream>
  2. #include <random>
  3. int main ()
  4. {
  5. std::random_device rd;
  6. std::cout << "default random_device characteristics:" << std::endl;
  7. std::cout << "minimum: " << rd.min() << std::endl;
  8. std::cout << "maximum: " << rd.max() << std::endl;
  9. std::cout << "entropy: " << rd.entropy() << std::endl;
  10. std::cout << "a random number: " << rd() << std::endl;
  11. return 0;
  12. }

seed_seq

seed_seq::seed_seq

  1. seed_seq();
  2. template<class T>
  3. seed_seq (initializer_list<T> il);
  4. template<class InputIterator>
  5. seed_seq (InputIterator first, InputIterator last);
  1. #include <iostream>
  2. #include <random>
  3. #include <string>
  4. #include <array>
  5. int main ()
  6. {
  7. std::seed_seq seed1;
  8. std::seed_seq seed2 = {102,406,7892};
  9. std::string foo = "Seeding a RNG";
  10. std::seed_seq seed3 (foo.begin(),foo.end());
  11. std::cout << "generating a sequence of 5 elements:" << std::endl;
  12. std::array<unsigned,5> sequence;
  13. seed3.generate(sequence.begin(),sequence.end());
  14. for (unsigned x:sequence) {std::cout << x << std::endl;}
  15. return 0;
  16. }

seed_seq::generate

  1. template <class RandomAccessIterator>
  2. 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.

uniform_int_distribution

  1. template <class IntType = int> class uniform_int_distribution;

uniform_int_distribution::uniform_int_distribution

  1. explicit uniform_int_distribution ( result_type a = 0,
  2. result_type b = numeric_limits<result_type>::max() );
  3. explicit uniform_int_distribution ( const param_type& parm );

uniform_real_distribution

  1. template <class RealType = double> class uniform_real_distribution;

uniform_real_distribution::uniform_real_distribution

  1. explicit uniform_real_distribution ( result_type a = 0.0, result_type b = 1.0 );
  2. explicit uniform_real_distribution ( const param_type& parm );

normal_distribution

  1. template <class RealType = double> class normal_distribution;

normal_distribution::normal_distribution

  1. explicit normal_distribution ( result_type mean = 0.0, result_type stddev = 1.0 );
  2. explicit normal_distribution ( const param_type& parm );

discrete_distribution

  1. template <class IntType = int> class discrete_distribution;

discrete_distribution::discrete_distribution

  1. discrete_distribution();
  2. template <class InputIterator>
  3. discrete_distribution (InputIterator first, InputIterator last);
  4. discrete_distribution (initializer_list<double> il);
  5. template <class UnaryOperation>
  6. discrete_distribution (size_t nw, double xmin, double xmax, UnaryOperation fw);
  7. explicit discrete_distribution (const param_type& parm);

example

  1. #include <iostream>
  2. #include <chrono>
  3. #include <random>
  4. #include <functional>
  5. #include <array>
  6. int main()
  7. {
  8. // construct a trivial random generator engine from a time-based seed:
  9. unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
  10. std::default_random_engine generator (seed);
  11. std::array<double,4> init = {1.0,2.0,3.0,4.0};
  12. std::discrete_distribution<int> first;
  13. std::discrete_distribution<int> second (init.begin(),init.end());
  14. std::discrete_distribution<int> third {0.1,0.2,0.3,0.4};
  15. // display probabilities:
  16. std::cout << "displaying probabilities:";
  17. std::cout << std::endl << "first : ";
  18. for (double x:first.probabilities()) {
  19. std::cout << x << " ";
  20. }
  21. std::cout << std::endl << "second: ";
  22. for (double x:second.probabilities()) {
  23. std::cout << x << " ";
  24. }
  25. std::cout << std::endl << "third : ";
  26. for (double x:third.probabilities()) {
  27. std::cout << x << " ";
  28. }
  29. return 0;
  30. }

  以上的分布查看C++参考即可看到很简单的API接口,至于由分布产生随机数更加统一使用operator()的方法即可

  1. template<class URNG>
  2. result_type operator()(URNG& g);
  3. template<class URNG>
  4. result_type operator()(URNG& g, const param_type& parm);

example
  标准把随机数抽象成随机数引擎和分布两部分.引擎用来产生随机数,分布产生特定分布的随机数(比如平均分布,正太分布等).
  标准提供三种常用的引擎:linear\_congruential\_engine,mersenne\_twister\_enginesubtract\_with\_carry\_engine.第一种是线性同余算法,第二种是梅森旋转算法,第三种带进位的线性同余算法.第一种是最常用的,而且速度也是非常快的; 第二种号称是最好的伪随机数生成器;第三种没用过....
  随机数引擎接受一个整形参数当作种子,不提供的话,会使用默认值. 推荐使用random\_device来产生一个随机数当作种子.(windows下爱咋整咋整,谁叫windows的random\_device是调用rand_s)

  1. #include <iostream>
  2. #include <chrono>
  3. #include <random>
  4. int main()
  5. {
  6. // construct a trivial random generator engine from a time-based seed:
  7. unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
  8. std::default_random_engine generator (seed);
  9. std::uniform_real_distribution<double> distribution (0.0,100.0);
  10. std::cout << "some random numbers between 0.0 and 100.0: " << std::endl;
  11. for (int i=0; i<10; ++i){
  12. std::cout << distribution(generator) << std::endl;
  13. }
  14. return 0;
  15. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注