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