About Random Number

Random number does NOT mean a different number every time. Random means something that can not be predicted logically.

Pseudo Random and True Random.

Computers work on programs, and programs are definitive set of instructions. So it means there must be some algorithm to generate a random number as well.

Random numbers generated through a generation algorithm are called pseudo random. It can be predicted.

In order to generate a truly random number on our computers we need to get the random data from some outside source. This outside source is generally our keystrokes, mouse movements, data on network etc.

We do not need truly random numbers, unless it is related to security (e.g. encryption keys) or the basis of application is the randomness (e.g. Digital roulette wheels).

How languages implement randomness

Most programming languages (like Python, Java, C++) implement pseudo-random number generators (PRNGs).

  • PRNGs are algorithms that produce sequences of numbers that appear random, but are completely determined by an initial value called the seed.
  • Once you set a seed, the sequence of random numbers is repeatable.

Algorithm Behind PRNGs

Algorithm Used In
Linear Congruential Generator (LCG) C, early Java, Python (older versions)
Mersenne Twister Python random, NumPy (default before v1.17)
PCG (Permuted Congruential Generator) numpy.random.default_rng()
Xoroshiro/Xoshiro Modern C/C++ libraries and game engines

Seed

Seed: Controlling the Sequence Setting a seed ensures repeatability (useful for debugging, testing, reproducibility). Without a seed, most languages auto-generate one using something like the current time or system entropy.

State

A pseudo-random number generator (PRNG) doesn’t truly generate random numbers, it produces a long, predictable sequence of numbers based on:

  • A starting point (seed)
  • An internal state that evolves as numbers are generated

So, the state is like a snapshot of the PRNG’s memory at a moment in time. If you save it, you can pause and resume the sequence exactly where you left off.

True Randomness (TRNGs)

Most of time we only need PRNG, but some applications (e.g. cryptography) need true randomness: Collected from physical sources like:

  • Mouse movement
  • Atmospheric noise
  • Hardware random number generators

Python Random module

Python Random module implements pseudo-random number generators for various distributions. (Other Languea, Library will do smiliar things for Random)

  • For integers, there is uniform selection from a range.
  • For sequences, there is uniform selection of a random element, a function to generate a random permutation of a list in-place, and a function for random sampling without replacement.
  • Almost all module functions depend on the basic function random(), which generates a random float uniformly in the half-open range 0.0 <= X < 1.0.
  • Python uses the Mersenne Twister as the core generator.
  • It produces 53-bit precision floats and has a period of 2**19937-1.
  • It is completely unsuitable for cryptographic purposes.
  • For security or cryptographic uses, see the secrets module.
  • The functions supplied by this module are actually bound methods of a hidden instance of the random.Random class. You can instantiate your own instances of Random to get generators that don’t share state.

Bookkeeping

random.seed(a=None, version=2)

Initialize the random number generator.

  • If a is omitted or None, the current system time is used.
  • If a is an int, it is used directly.

random.getstate()

Return an object capturing the current internal state of the generator. This object can be passed to setstate() to restore the state.

random.setstate(state)

It can restore the state for the random generator.

For Sequences random selection

random.choice(seq)

Return a random element from the non-empty sequence seq.

random.shuffle(x)

Shuffle the sequence x in place. (please note that, it will mutate the sequence). To shuffle an immutable sequence and return a new shuffled list, use sample(x, k=len(x)) instead.

random.sample(population, k, *, counts=None)

Return a k length, new list of unique elements chosen from the population sequence or set. Used for random sampling without replacement.

NumPy Random module

Python built-in random module vs. numpy.random

Feature random (Python built-in) numpy.random (NumPy)
Library Built-in (import random) Requires NumPy (import numpy as np)
Speed Slower Much faster (optimized with C under the hood)
Data Types Works with basic types (int, float) Works with NumPy arrays
Best For Simple randomness (games, small apps) Scientific computing, machine learning
Random Arrays Not supported Easily generates arrays of random numbers
Distributions Basic (uniform, normal) Extensive (normal, binomial, Poisson, etc.)
Seeding random.seed() np.random.seed() or np.random.default_rng()
Modern Interface Basic only np.random.default_rng() (recommended in NumPy ≥ 1.17)

Python random:

import random
random.seed(0)
print(random.randint(1, 10))  # Random int between 1 and 10

NumPy random:

import numpy as np
rng = np.random.default_rng(0)
print(rng.integers(1, 11))    # Same, but faster and better control