Use randomness to make an algorithm simpler, faster, or possible at all.

Why randomness helps

ReasonExample
Defeats adversarial inputrandomised pivot in quicksort; a random hash base
Avoids worst cases without analysistreaps instead of red-black trees
Breaks symmetryleader election, Karger’s contraction
Samples instead of enumeratingMonte Carlo integration
Finds witnesses fastMiller-Rabin — most bases are witnesses
Simplifies the coderandomised incremental geometry

The recurring theme: an adversary can construct a bad input for a deterministic algorithm, but cannot predict your coin flips.

The two classes

Las VegasMonte Carlo
Answeralways correctcorrect with probability
Running timerandomfixed
Examplesquicksort, Pollard’s rho, WelzlMiller-Rabin, Karger, hashing
Convertrun until successrepeat and take the majority / any success

See Las Vegas vs Monte Carlo.

The essential tools

Random number generation

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
long long r = uniform_int_distribution<long long>(1, n)(rng);
shuffle(v.begin(), v.end(), rng);

Never use a fixed seed, rand(), or random_shuffle

  • A fixed seed is predictable and hackable — Codeforces problems include anti-tests for common seeds.
  • rand() is low quality and its low bits are often nearly non-random; rand() % n is biased.
  • random_shuffle is removed in C++17 and used rand() internally.
  • Seed from the clock (and ideally XOR in an address for extra entropy).

Concentration bounds

Chernoff: for independent with ,

Markov: for non-negative .

Union bound: — crude but almost always sufficient.

These say “a sum of independent bounded variables is very close to its mean”, which is what licenses the phrase “with high probability”.

Backwards analysis

“What is the probability that the last element added was important?” Gives clean expected bounds for randomised incremental algorithms — see Seidel’s LP, Welzl, and randomised Delaunay.

Randomised algorithms worth knowing

AlgorithmRandomness used for
Quicksort / nth_elementpivot choice
Treapnode priorities
Skip listlevel assignment
Miller-Rabinwitness bases
Pollard’s rhothe pseudo-random walk
Karger’s min cutedge contraction
Welzl’s enclosing circleinsertion order
String hashingthe base
Tutte matrix matchingmatrix entries
Freivalds’ matrix product checktest vector
Simulated annealingmove acceptance
Reservoir samplingwhich item to keep

Freivalds’ algorithm

Verify for matrices in instead of : pick a random 0/1 vector and check . If , the test fails with probability ; repeat times for error .

A perfect illustration: verifying is easier than computing, and randomness closes the gap.

Derandomisation

Some randomised algorithms can be made deterministic:

  • Method of conditional expectations — fix the random choices one at a time, always taking the branch that keeps the conditional expectation good.
  • Pairwise independence — many analyses need only pairwise independence, which requires random bits and can then be enumerated.
  • Fixed witness setsMiller-Rabin with 12 fixed bases is deterministic for all 64-bit inputs.

Usually not worth it in practice, but the conditional-expectation method is a genuine proof technique.

See also: Las Vegas vs Monte Carlo · Random Shuffling · Birthday Paradox