This page provides algorithms for producing pseudo-random numbers. They are random because they have no discernable patterns, but they are not truly random because they are mathematically determined.

Scientifically, pseudo-random numbers are used to randomly allocate cases into different groups in controlled experiments, or to create random events in data modelling. Pseudo-random numbers are not considered encryption grade, and should not be used to encrypt information with serious security implications.

The basic random number generator produces a real number between 0 and 1. These can then be further converted into the following

- Random real numbers that are normally distributed
- Integers within a range
- Clustes of ranged numbers in random order (shuffled)

The following random number generators are demonstrated on this page. It should be noted that each one generates different sequences that have different properties.

- Javascript
**Math.random()** function generates a real number between 0 and 1 to 16 decimal places. However it cannot repeat the same sequence.
- Javascript program using the
**Ran3** algorithm (see references). This allows the assignment of a random seed, so that the same sequence of random numbers can be repeatedly generated. An additional feature is that, although the random number is generated to only 9 decimal places, the algorithm is integer based and portable, in that the same program written in any language in any operating system will produce the same sequences.
**R** and **Python codes** also allows the assignment of a random seed to generate the same sequence repeatedly. It also provides functions where random numbers that are normally or exponentially distributd can also be generated.
**Please Note: **Different programs will generate different sequences of random number. Even the same program may generate different sequences if the version of the algorithm is changed or the capacity of the memories upgraded (8, 16, 32, 64 ... bits). These changes do not matter unless the same sequence is to be used repeatedly.

Random Real Numbers
Random Normally Distributed Numbers
Random Integers
Clusters in Random Order
**Note:**

- If the value of 0 is used for random seed, then the Javascript random number generator is used, and the sequence cannot be repeated
- If the value >=1 is used for random seed, then the Rans3 algorithm (see reference) us used, and the same sequence can be reproduced with the same seed value

**Reference: **Press WH, Flannery BP,Teukolsky SA, Vetterling WT (1994).
Numerical recipes in Pascal Ed. 1, IBSN 0-521-37516-9. p.221

Calculation are presented in

maroon and results produced presented in

navy
**Set Random Seed**

# set.seed(i): sets seed with an integer. This is used so that the random sequence can be reproduced
# If seed is not set, random sequence is still produced, bur=t cannot be repeated
set.seed(423)

**Random Real Numbers**
# runif(n): produces vector of n real numbers between 0 and 1
runif(5)

0.1089715 0.5973455 0.9726307 0.7973768 0.2278427

# runif(n, minv, maxv): produces vector of n real numbers bewtween (but not including) minv and maxv
runif(5,1,2)

1.518983 1.692926 1.810445 1.101946 1.916665

**Normally Distributed Real Numbers**
# rnorm(n): produces vector of n real numbers that are normally distributed with mean=0 and Sd=1
rnorm(4)

-0.83275158 -0.09037604 1.24637161 -0.86855455

# rnorm(n, mean=m, sd=s): produces vector of n real numbers that are normally distributed with mean=m and Sd=s
rnorm(4, mean=50, sd=10)

57.87787 52.37559 40.71722 50.82922

**Exponentially Distributed Real Numbers**
# rexp(n, 1/m): produces vector of n real numbers that are exponentially distributed with mean=m
# note; 1/mean =lambda. As mean is the commonly referred to value, 1/mean is used
rexp(4, 1/50)

59.572524 100.594748 8.991593 21.194672

**Integers**
# sample(minv:maxv, n, replace=TRUE/FALSE) produces vector of n integers from minv to maxv (inclusive)
# note: if replace=false then n must be <= range or an error will occur
sample(1:3, 3, replace=TRUE)

2 2 3

sample(1:3, 3, replace=FALSE)

1 3 2

**clusters in random order**
# nCluster = number of clusters
# minv, maxv are minimum and maximum values in each cluster (inclusive)
RandomClusters<-function(nCluster,minv, maxv)
{
siz = maxv - minv + 1
resMx = vector()
for(i in 1:nCluster)
{
resMx<-rbind(resMx,sample(minv:maxv, siz, replace=FALSE))
}
return(resMx)
}
RandomClusters(4,1,3) # testing

2 1 3
3 1 2
1 2 3
3 1 2

Python provides an extensive library to handle random numbers, and only the common procedurs are produced here. Full documentation from the Python library can be accessed via

https://docs.python.org/3/library/random.html or

https://www.w3schools.com/python/module_random.asp
Calculation are presented in maroon and results produced presented in navy

""" Note: random must be imported if functions are used seprately """
import random as rnd

**SowSeed is required if the same sequence is to be repeated**
def SetSeed(seed):
""" set seed to enable same sequence to be produced """
rnd.seed(seed)
SetSeed(123)

**Random real number between values of 0 to 1, evenly distributed**
def RandomReal(n):
""" list of n random real numbers values between 0 and 1 """
lst = []
for i in range(n): lst.append(rnd.random())
return lst
print(RandomReal(5)) #testing

[0.052363598850944326, 0.08718667752263232, 0.4072417636703983, 0.10770023493843905, 0.9011988779516946]

**Normally distributed random number with mean and Standard Deviations defined**
def RandomNorm(n,m,s):
""" list of n normally distributed random numbers
with mean of m and Standard Deviation of s """
lst = []
for i in range(n): lst.append(rnd.gauss(m,s))
return lst
print(RandomNorm(5,0,1)) #testingdef

[1.204152783694542, 0.2943273329185672, -0.9654236953375986, 1.7000629304986967, 0.4876079543679099]

**Exponentially distributed random number with mean defined**
def RandomExponential(n,m):
""" list of n exponentially distributed random numbers with mean of m """
lmbd = 1 / m # lambda = 1 / mean
lst = []
for i in range(n): lst.append(rnd.expovariate(lmbd))
return lst
print(RandomExponential(5,7)) #testing

[2.843119589746403, 1.9687773986509844, 0.0117036535688458, 4.012330997488666, 0.6418410918490749]

**Random integers in a range**
def RandomInteger(n,minv,maxv):
""" list of n integers ranged from minv to maxv (inclusive) """
lst = []
for i in range(n): lst.append(rnd.randint(minv,maxv))
return lst
print(RandomInteger(5,1,3)) #testing

[3, 2, 1, 1, 2]

**Shuffle a list into random order**
def ShuffleAList(aList):
""" shuffles a list into random order """
rnd.shuffle(aList)
return aList
print(ShuffleAList([1,2,3,4])) #testing

[2, 3, 1, 4]

**Matrix of values where each row is a list of values in a defined range but in random order**
def RandomOrder(n,minv, maxv):
""" n rows of lists ranged minv to maxv (inclusive) in random order """
inList = []
for i in range(minv, maxv+1): inList.append(i)
res = [[0 for c in range(len(inList))] for r in range(n)]
for j in range(n):
j = j
rnd.shuffle(inList)
for k in range(len(inList)):
res[j][k] = inList[k]
return res
print(RandomOrder(4, 1, 3)) #testing

[[2, 3, 1], [3, 1, 2], [3, 2, 1], [3, 2, 1]]

**Cryptographic Grade Random Number**
The same codes listed above can be used to create cryptographic grade random numbers, with the following differences