random_demo.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /* boost random_demo.cpp profane demo
  2. *
  3. * Copyright Jens Maurer 2000
  4. * Distributed under the Boost Software License, Version 1.0. (See
  5. * accompanying file LICENSE_1_0.txt or copy at
  6. * http://www.boost.org/LICENSE_1_0.txt)
  7. *
  8. * $Id$
  9. *
  10. * A short demo program how to use the random number library.
  11. */
  12. #include <iostream>
  13. #include <fstream>
  14. #include <ctime> // std::time
  15. #include <boost/random/linear_congruential.hpp>
  16. #include <boost/random/uniform_int.hpp>
  17. #include <boost/random/uniform_real.hpp>
  18. #include <boost/random/variate_generator.hpp>
  19. #include <boost/generator_iterator.hpp>
  20. // This is a typedef for a random number generator.
  21. // Try boost::mt19937 or boost::ecuyer1988 instead of boost::minstd_rand
  22. typedef boost::minstd_rand base_generator_type;
  23. // This is a reproducible simulation experiment. See main().
  24. void experiment(base_generator_type & generator)
  25. {
  26. // Define a uniform random number distribution of integer values between
  27. // 1 and 6 inclusive.
  28. typedef boost::uniform_int<> distribution_type;
  29. typedef boost::variate_generator<base_generator_type&, distribution_type> gen_type;
  30. gen_type die_gen(generator, distribution_type(1, 6));
  31. // If you want to use an STL iterator interface, use iterator_adaptors.hpp.
  32. boost::generator_iterator<gen_type> die(&die_gen);
  33. for(int i = 0; i < 10; i++)
  34. std::cout << *die++ << " ";
  35. std::cout << '\n';
  36. }
  37. int main()
  38. {
  39. // Define a random number generator and initialize it with a reproducible
  40. // seed.
  41. base_generator_type generator(42);
  42. std::cout << "10 samples of a uniform distribution in [0..1):\n";
  43. // Define a uniform random number distribution which produces "double"
  44. // values between 0 and 1 (0 inclusive, 1 exclusive).
  45. boost::uniform_real<> uni_dist(0,1);
  46. boost::variate_generator<base_generator_type&, boost::uniform_real<> > uni(generator, uni_dist);
  47. std::cout.setf(std::ios::fixed);
  48. // You can now retrieve random numbers from that distribution by means
  49. // of a STL Generator interface, i.e. calling the generator as a zero-
  50. // argument function.
  51. for(int i = 0; i < 10; i++)
  52. std::cout << uni() << '\n';
  53. /*
  54. * Change seed to something else.
  55. *
  56. * Caveat: std::time(0) is not a very good truly-random seed. When
  57. * called in rapid succession, it could return the same values, and
  58. * thus the same random number sequences could ensue. If not the same
  59. * values are returned, the values differ only slightly in the
  60. * lowest bits. A linear congruential generator with a small factor
  61. * wrapped in a uniform_smallint (see experiment) will produce the same
  62. * values for the first few iterations. This is because uniform_smallint
  63. * takes only the highest bits of the generator, and the generator itself
  64. * needs a few iterations to spread the initial entropy from the lowest bits
  65. * to the whole state.
  66. */
  67. generator.seed(static_cast<unsigned int>(std::time(0)));
  68. std::cout << "\nexperiment: roll a die 10 times:\n";
  69. // You can save a generator's state by copy construction.
  70. base_generator_type saved_generator = generator;
  71. // When calling other functions which take a generator or distribution
  72. // as a parameter, make sure to always call by reference (or pointer).
  73. // Calling by value invokes the copy constructor, which means that the
  74. // sequence of random numbers at the caller is disconnected from the
  75. // sequence at the callee.
  76. experiment(generator);
  77. std::cout << "redo the experiment to verify it:\n";
  78. experiment(saved_generator);
  79. // After that, both generators are equivalent
  80. assert(generator == saved_generator);
  81. // as a degenerate case, you can set min = max for uniform_int
  82. boost::uniform_int<> degen_dist(4,4);
  83. boost::variate_generator<base_generator_type&, boost::uniform_int<> > deg(generator, degen_dist);
  84. std::cout << deg() << " " << deg() << " " << deg() << std::endl;
  85. {
  86. // You can save the generator state for future use. You can read the
  87. // state back in at any later time using operator>>.
  88. std::ofstream file("rng.saved", std::ofstream::trunc);
  89. file << generator;
  90. }
  91. return 0;
  92. }