Generating Random Numbers

  1. Overview
    1. Software must often use random numbers (e.g., creating an AI that chooses randomly between multiple choices, simulating a dice roll, etc.)
    2. Computers typically use random number generators that use mathematical equations to produce pseudorandom numbers, numbers that are not truly random but are nearly impossible to distinguish from truly random numbers
    3. These pseudorandom number generators will produce the same random numbers every time unless they are initialized with a random seed
    4. The seed is often based on the current date and time, which is always unique
  2. Example which displays 20 random integers
    #include <iostream>
    #include <cstdlib>   // srand and rand functions
    #include <ctime>     // time function
    using namespace std;
    
    void main()
    {
    	// Seed the random number generator
    	srand(time(NULL));
    	
    	// Output 20 random numbers
    	for (int i = 1; i <= 20; i++)
    		cout << rand();
    }
    
    1. srand(seed) seeds the random number generator with the return value of time, which is type-casted into an unsigned integer (an integer that can't be negative)
    2. time(NULL) returns the number of seconds which have elapsed since Jan 1, 1970 (called Unix time or Epoch time)
    3. rand() returns back a random number between 0 and RAND_MAX (at least 32,767)
    4. Usually the random numbers we want to produce are bound by an upper and lower limit, so we mod the return value from rand
      // Output 20 random numbers between 1 and 10
      for (int i = 1; i <= 20; i++)
      	cout << rand() % 10 + 1;
      
    5. Simulate flipping a coin twenty times
      for (int i = 1; i <= 20; i++)
      {
      	// Number will be 0 or 1
      	if (rand() % 2 == 0)
      		cout << "Heads\n";
      	else
      		cout << "Tails\n";
      }
      
  3. Common mistakes
    1. Forgetting to call srand will result in the same numbers being chosen every time your program runs!
    2. srand only needs to be called once (usually in main). Calling it multiple times is unnecessary and in some cases could cause your program to choose the same random numbers repeatedly
      // Output the SAME 20 random numbers!
      for (int i = 1; i <= 20; i++)
      {
      	srand(time(NULL));
      	cout << rand() % 10 + 1;
      }
      
  4. Better random number generators for C++
    1. rand is an old C function that does not produce a uniform distribution of random numbers, and the numbers eventually repeat
    2. C++ provides newer methods to produce better random numbers
      #include <random>
      
      // Create random device object
      random_device rd;
      
      // Create default random engine object that is seeded using random device
      default_random_engine engine(rd());
      
      // Create a distribution object that has an equal chance of 
      // returning ints between 1 and 100 (inclusive)
      uniform_int_distribution<int> dist(1, 100);
      
      // Get a random number using the distribution and engine objects
      int rand_num = dist(engine);
      
    3. See the documentation: Pseudo-random number generation
  5. Learn more about generating truly random numbers at random.org