Random-number generation

Chez Scheme provides a built-in procedure random that is often helpful in modelling real-world phenomena that do not follow any obvious algorithms and are not predictable.

When the random procedure is given an exact positive integer as argument, it returns some non-negative integer less than the argument, but not always the same one. Over a long series of calls, you'll get back each non-negative integer less than the argument about equally often. So, for example, the call (random 20) always yields some integer in the range from 0 to 19, and over a long series of calls you can expect each of those values to be returned about one-twentieth of the time.

(random 20) ===> 4
(random 20) ===> 17
(random 20) ===> 16

When the argument to random is an inexact positive real (typically specified by a numeral containing a decimal point), random returns some non-negative real value less than the argument. Over a long series of identical calls, the values returned will be distributed approximately evenly throughout the interval from 0.0 (inclusive) to the value of the argument (exclusive).

(random 1.5) ===> 0.046003446339158316
(random 1.5) ===> 1.3329912409120568
(random 1.5) ===> 1.4584015323556465
(random 1.5) ===> 0.14671341559491913
(random 1.5) ===> 1.1500817949427606

A typical use of random is to simulate the rolling of an ordinary six-sided die. The roll-a-die procedure returns a random integer in the range from 1 to 6:

(define roll-a-die
  (lambda ()
    (+ 1 (random 6))))

Note that roll-a-die takes no arguments. To invoke it, just write its name between parentheses: (roll-a-die).

Another common application of random is to select an element at random from a non-empty list. The random-element procedure performs this operation on a given list:

(define random-element
  (lambda (ls)
    (list-ref ls (random (length ls)))))

(random-element '(a b c d e f g)) ===> c
(random-element '(a b c d e f g)) ===> f
(random-element '(a b c d e f g)) ===> b
(random-element '(111 112 114 118 126)) ===> 112
(random-element '(only)) ===> only

In English: To choose a random element from a list, obtain a random non-negative integer less than the length of that list and select the element at that position in the list.

  1. Define a toss-a-coin procedure that takes no arguments and returns either the string "heads" or the string "tails", about equally often over a long series of calls.

  2. Define a procedure named roll-two-dice that takes no arguments, simulates the independent rolling of two dice, and returns the total of the numbers on the faces that turn up.

  3. Define a procedure named random-Boolean-list that takes one argument, a non-negative integer, and constructs and returns a list of the length specified by that argument. Each element of the list should be one of the Boolean values #t and #f, chosen independently, at random, and with equal probability. For instance, the call (random-Boolean-list 4) might return the value (#t #t #f #t).

  4. According to the Des Moines Register (September 10, 1997, page 1M), registered voters in Iowa have declared the following party affiliations:

    Democratic Party    558801
    Reform Party            81
    Republican Party    583897
    unaffiliated        583002
    --------------------------
      total            1725781
    

    Define a procedure named random-voter-affiliation that takes no arguments and returns the symbol Democrat 558801/1725781 of the time, the symbol Reform 81/1725781 of the time, the symbol Republican 583897/1725781 of the time, and the symbol mugwump 583002/1725781 of the time.


This document is available on the World Wide Web as

http://www.math.grin.edu/~stone/courses/scheme/random-number-generation.html

created February 7, 1997
last revised September 11, 1997

John David Stone (stone@math.grin.edu)