Sunday, 23 March 2014

Random Numbers

Intro
This tutorial provides a brief introduction to the random number functions that come as part of the C++ standard library, namely rand() and srand().
rand() and RAND_MAX
The C++ standard library includes a pseudo random number generator for generating random numbers. In order to use it we need to include the <cstdlib> header. To generate a random number we use the rand() function. This will produce a result in the range 0 to RAND_MAX, where RAND_MAX is a constant defined by the implementation.
Here's a piece of code that will generate a single random number:
  1. #include <cstdlib>
  2. #include <iostream>
  3. using namespace std;
  4. int main()
  5. {
  6. int random_integer = rand();
  7. cout << random_integer << endl;
  8. }
The value of RAND_MAX varies between compilers and can be as low as 32767, which would give a range from 0 to 32767 for rand(). To find out the value of RAND_MAX for your compiler run the following small piece of code:
  1. #include <cstdlib>
  2. #include <iostream>
  3. using namespace std;
  4. int main()
  5. {
  6. cout << "The value of RAND_MAX is " << RAND_MAX << endl;
  7. }
srand()
The pseudo random number generator produces a sequence of numbers that gives the appearance of being random, when in fact the sequence will eventually repeat and is predictable.
We can seed the generator with the srand() function. This will start the generator from a point in the sequence that is dependent on the value we pass as an argument. If we seed the generator once with a variable value, for instance the system time, before our first call of rand() we can generate numbers that are random enough for simple use (though not for serious statistical purposes).
In our earlier example the program would have generated the same number each time we ran it because the generator would have been seeded with the same default value each time. The following code will seed the generator with the system time then output a single random number, which should be different each time we run the program.
  1. #include <cstdlib>
  2. #include <ctime>
  3. #include <iostream>
  4. using namespace std;
  5. int main()
  6. {
  7. srand((unsigned)time(0));
  8. int random_integer = rand();
  9. cout << random_integer << endl;
  10. }
Don't make the mistake of calling srand() every time you generate a random number; we only usually need to call srand() once, prior to the first call to rand().
Generating a number in a specific range
If we want to produce numbers in a specific range, rather than between 0 and RAND_MAX, we can use the modulo operator. It's not the best way to generate a range but it's the simplest. If we use rand()%n we generate a number from 0 to n-1. By adding an offset to the result we can produce a range that is not zero based. The following code will produce 20 random numbers from 1 to 10:
  1. #include <cstdlib>
  2. #include <ctime>
  3. #include <iostream>
  4. using namespace std;
  5. int main()
  6. {
  7. srand((unsigned)time(0));
  8. int random_integer;
  9. for(int index=0; index<20; index++){
  10. random_integer = (rand()%10)+1;
  11. cout << random_integer << endl;
  12. }
  13. }
A better method, though slightly more complicated, is given below. This overcomes problems that are sometimes experienced with some types of pseudo random number generator that might be supplied with your compiler. As before, this will output 20 random numbers from 1 to 10.
  1. #include <iostream>
  2. #include <ctime>
  3. #include <cstdlib>
  4. using namespace std;
  5. int main()
  6. {
  7. srand((unsigned)time(0));
  8. int random_integer;
  9. int lowest=1, highest=10;
  10. int range=(highest-lowest)+1;
  11. for(int index=0; index<20; index++){
  12. random_integer = lowest+int(range*rand()/(RAND_MAX + 1.0));
  13. cout << random_integer << endl;
  14. }
  15. }
Conclusion
If you need to use a pseudo random number generator for anything even remotely serious you should avoid the simple generator that comes with your compiler and use something more sophisticated instead. That said, rand() still has its place and you may find it useful.

No comments:

Post a Comment