A colouring nobody can write down
Colour every edge of the complete graph red or blue. Ramsey's theorem says that if is large enough there is always a monochromatic — vertices all of whose connecting edges have the same colour. The least such is the Ramsey number . Among any six people there are three mutual acquaintances or three mutual strangers (); (Greenwood and Gleason, 1955); and already is unknown — it lies between (Exoo, 1989) and (Angeltveit and McKay, 2024). Erdős and Szekeres (1935) showed , and after decades of small improvements Campos, Griffiths, Morris and Sahasrabudhe (2023) proved for some .
For a lower bound we need, for large , a colouring of with no monochromatic . Nobody knows how to construct one with exponential in : Erdős offered a prize for an explicit colouring with , and the best explicit constructions are still far from exponential. Yet in 1947 Erdős proved in a few lines that such colourings exist with : colour at random. The expected number of monochromatic is less than , so some colouring has none. This lower bound has not been improved exponentially since; only the constant factor has moved (Spencer, 1975, by the local lemma).
That is the probabilistic method: to show an object with a property exists, define a probability distribution on objects and show that a random object has the property with positive probability. On a finite space it is a counting argument in disguise — the Lean proof below is pure counting — but the language of probability (independence, expectation, concentration) is what makes the counts tractable. This lesson assumes graph theory (including ) and probability theory (expectation, variance, Chebyshev's inequality).
Averages, deletions, and rare bad events
Five ideas organise the subject.
- The first moment. If is integer-valued and , then . If , then for some outcome. Expectation is easy to compute because it is linear, with no independence needed: the expected number of bad configurations is the sum of their probabilities.
- Alteration. If a random object has a few defects, delete or repair them: a random colouring of with on average monochromatic 's yields, after deleting a vertex from each, a good colouring on vertices.
- The second moment. To show that with high probability it is not enough that ; we also need to be concentrated: .
- The local lemma. If bad events are individually unlikely and each depends on only a few others, then with positive (possibly tiny) probability none occurs — even when there are far too many for the union bound.
- Concentration. Sums of many independent small contributions are exponentially unlikely to deviate far from their mean (Chernoff), much better than Chebyshev's polynomial bound.
The method proves existence, but its proofs often say little about how to find the object. Sometimes they do: if good objects are common, sampling finds one fast; the method of conditional expectations and the Moser–Tardos algorithm turn some proofs into deterministic or efficient algorithms.
Definitions
Definition— Ramsey numbers
is the least such that every red/blue colouring of the edges of contains a red or a blue . Equivalently, every graph on vertices contains a clique of size or an independent set of size . So means: some colouring of has no monochromatic .
Definition— the random graph G(n, p)
is the graph on in which each of the possible edges is present independently with probability . is the uniform distribution on all graphs — equivalently, a uniformly random red/blue colouring of . A property holds with high probability if its probability tends to as .
Definition— Markov's and Chebyshev's inequalities
For and , (Markov). For any with finite variance, (Chebyshev). Taking in Markov for integer gives the first-moment method: . Taking in Chebyshev gives the second-moment method: .
Definition— dependency graph
Events have a dependency graph on if each is mutually independent of the family of events not adjacent to it. (Pairwise independence is not enough; mutual independence of from the whole family is required.) If all events are determined by independent random variables and , are joined whenever they share a variable, this is a dependency graph.
Definition— girth, chromatic number, independence number
The girth of a graph is the length of its shortest cycle; the chromatic number is the least number of colours in a proper vertex colouring; the independence number is the largest size of a set of pairwise non-adjacent vertices. Each colour class of a proper colouring is independent, so .
Warm-up examples
Example— Large cuts
Every graph with edges has a bipartition of its vertices that cuts at least edges. Proof. Put each vertex on side or by independent fair coin flips. An edge is cut with probability , so by linearity the expected number of cut edges is , and some bipartition does at least as well as the average. Note that the indicator variables "edge is cut" are pairwise independent but not mutually independent (the three edges of a triangle cannot all be cut) — linearity does not care.
Example— Tournaments with many Hamiltonian paths (Szele, 1943)
A tournament orients every edge of . Orient each edge by a fair coin. For each of the orderings of the vertices, the probability that is a directed path is . So the expected number of Hamiltonian paths is , and some tournament has at least that many — one of the first applications of the method.
Example— Independent sets (Caro, 1979; Wei, 1981)
Every graph satisfies . Proof. Order the vertices uniformly at random and let be the set of vertices that come before all their neighbours. is independent, and with probability (among and its neighbours, each is equally likely to be first). So . By convexity this is at least , where is the average degree — a form of Turán's theorem.
Example— Two-colouring hypergraphs (Erdős, 1963)
A family of sets, each of size , with , can be 2-coloured so that no set is monochromatic. Proof. Colour the points at random; each set is monochromatic with probability , and the expected number of monochromatic sets is . This is the same calculation as Theorem 1, with the -sets of vertices replaced by arbitrary sets.
The main theorems
Theorem— Theorem 1 (Erdős, 1947)
If , then . In particular for every .
Proof
Colour the edges of independently and uniformly at random. For a fixed set of vertices, the edges inside are all red with probability and all blue with the same probability, so . Let be the number of monochromatic -sets. By linearity, , so : some colouring has no monochromatic , and .
Now let and , so . Using and ,
because for , i.e. : true for (), and each step multiplies the left side by and the right side by .
∎
The Lean formalisation below proves exactly this, phrased as counting: at most of the colourings have a monochromatic , and this is fewer than all of them. The proof gives no colouring — and for it is weak (it shows only ), while the explicit Paley colouring of (red when is a square mod ) shows . The first experiment checks both. For large the roles reverse: random colourings beat every known construction.
Theorem— Theorem 2 (the deletion method)
For all and , . Choosing optimally gives , a factor better than the best bound obtainable from Theorem 1, which is .
Proof
With as above, , so some colouring has . Delete one vertex from each monochromatic -set: at least vertices remain, and the colouring restricted to them has no monochromatic . So . For the asymptotics, and one takes chosen so that ; see Alon–Spencer, §3.1.
∎
Theorem— Theorem 3 (Erdős, 1959: high girth and high chromatic number)
For all integers there is a graph with girth greater than and chromatic number greater than .
Proof
Fix , let and consider for large .
Few short cycles. Let be the number of cycles of length at most . A cycle of length is determined by an ordered sequence of distinct vertices up to rotations and reflections, so
since . By Markov's inequality, .
No large independent sets. Let . The probability that some -set is independent is at most
Deletion. For large both bad events have probability less than , so some graph on vertices has and . Delete one vertex from each cycle of length at most . The resulting graph has more than vertices, girth greater than , and . Therefore
which exceeds for large .
∎
Explicit graphs with these properties were found later (Lovász, 1968, and, much more elegantly, the Ramanujan graphs of Lubotzky, Phillips and Sarnak, 1988), but the random proof came first and is still the simplest. Locally (within distance of any vertex) looks like a tree, yet globally it needs many colours: chromatic number is not a local property.
Theorem— Theorem 4 (second moment: the threshold for triangles)
Let be the number of triangles in . If then ; if then . So is a threshold for containing a triangle.
Proof
over the triples , and . If , (first moment). If , compute
The first sum is at most . If share at most one vertex they have no common edge, so and are independent and the covariance is . If they share two vertices (one edge), , and there are at most such ordered pairs. Hence and, by the second-moment method,
∎
Erdős and Rényi (1960) found such thresholds for many properties; at the random graph undergoes a phase transition: for all components have vertices, while for a unique giant component with a positive fraction of the vertices appears.
Theorem— Theorem 5 (the Lovász local lemma)
Let be events with dependency graph . If there are numbers with
then . Symmetric form: if every , every vertex of has degree at most , and , then with positive probability no occurs.
Proof
Claim: for every and with ,
We induct on . Split with and , and write , . If , the conditional probability is by mutual independence. Otherwise
The numerator is at most . For the denominator, list ; then
by the induction hypothesis (each conditioning set has fewer than events). The ratio is at most , proving the claim. (Positivity of the conditioning probabilities follows along the way from the same product formula.)
Finally, . For the symmetric form take : then , using .
∎
The conclusion can be exponentially small — — which is why the union bound could not have found it.
Example— Applications of the local lemma
- Satisfiability. A -CNF formula in which each clause shares variables with at most other clauses is satisfiable: under a uniform random assignment each clause fails with probability , and . No bound on the number of clauses is needed.
- Hypergraph colouring. If every set of a family of -sets meets at most others, the family can be 2-coloured with no monochromatic set — compare the example above, which needed fewer than sets in total.
- Ramsey numbers (Spencer, 1975). With the events "the -set is monochromatic", two events are dependent only if the sets share an edge, so each depends on at most others; the symmetric local lemma gives — still the best lower bound known, a factor better than the deletion bound and better than the first moment.
Theorem— Theorem 6 (Chernoff bound for random signs)
Let be independent with , and . For every ,
Proof
For , Markov's inequality applied to gives . By independence, . Comparing Taylor series, , because , with strict inequality for (as for ). So , and gives . By symmetry the same bound holds for , which gives the two-sided bound.
∎
Compare Chebyshev: gives only . At Chebyshev gives and Chernoff . The same exponential-moment method gives bounds for sums of independent bounded variables (Hoeffding, 1963) and for Bernoulli sums around their mean.
Theorem— Corollary 7 (balancing sets)
For any subsets of an -element set there is a colouring of the points by with for every .
Proof
Colour uniformly at random and let . For each , is a sum of random signs, so by Theorem 6, . By the union bound, the probability that some set is unbalanced is less than .
∎
For this gives . Spencer's "six standard deviations" theorem (1985) improves it to , by a cleverer, partly non-random argument; Bansal (2010) and Lovett and Meka (2012) found efficient algorithms achieving .
Theorem— Theorem 8 (derandomisation, two ways)
- Conditional expectations. A cut of size at least can be found deterministically in polynomial time: place the vertices one by one on the side that cuts at least as many of the edges to already-placed vertices.
- Moser–Tardos (2010). In the setting of the local lemma with events determined by independent variables: start from a random assignment and, while some bad event occurs, resample the variables of one such event. Under the hypothesis of Theorem 5, the expected total number of resamplings is at most ; in the symmetric case, at most .
Proof of 1; 2 is cited. Let be the expected number of cut edges when the unplaced vertices are coloured at random, given the placements so far; initially . Placing the next vertex on side or changes to or with , so one choice does not decrease ; the greedy rule picks it (only the edges from to placed vertices change). At the end is the actual number of cut edges, which is at least . The Moser–Tardos theorem is proved by an ingenious "witness tree" counting argument (Moser and Tardos, J. ACM 57, 2010; Alon–Spencer, §5.7).
Conditional expectations also derandomise Theorem 1 — but only in time polynomial in , which is not an "explicit construction" in the sense of Ramsey theory (where one wants to compute the colour of an edge in time polynomial in ).
Explore: first moments and an explicit colouring
Expectation versus probability. In a group of people the expected number of pairs sharing a birthday is , yet the probability that at least one pair shares a birthday is about . Both facts are consistent: Markov's inequality only says . Change and compare the simulated probability with the expected count ; the first moment is an upper bound that becomes useless once it exceeds .
Shared birthdays: P(X ≥ 1) ≤ E[X]
E[X] = C(k, 2)/365 pairs; the first-moment bound holds, but it is far from the truth once E[X] is large.
- exact probability
- simulation, with 95% interval
991 of 2,000 groups of 23 shared a birthday
Simulated49.6% ± 2.2%
Exact50.7%
Simulated groups of 23 people: 49.6% had a shared birthday. The exact probability is 50.7%.
Evidence, not proofThis is a simulation of 2,000 groups (run 1) using a seeded random number generator. It is evidence, not proof: the exact values come from mathematics, and a new run gives slightly different numbers.
Exact formula: 1 − (365 × 364 × … × (365 − k + 1)) / 365ᵏ. It assumes 365 equally likely birthdays (no 29 February, no twins). With 23 people the chance first passes 1/2.
An explicit colouring for small . Below, the edges of a pentagon are the red edges of ; the five missing edges (the pentagram) are blue. Neither colour class contains a triangle — check with the Degrees tab that every vertex has two red and two blue edges — so . The Lean file checks this by computation. For large no explicit colouring comes close to the random one.
The pentagon colouring of K₅
Drawn edges are red, missing edges blue: no monochromatic triangle, so R(3, 3) > 5.
2 + 2 + 2 + 2 + 2 = 10 = 2 × 5
Every edge has two ends, so it adds exactly 2 to the total: the degrees add up to 10 = 2 × 5. This is the handshake lemma, Σ deg(v) = 2|E|.
Vertices of odd degree: 0. This number is always even, because the total is even.
A complete formal proof of Erdős's theorem
On a finite probability space with the uniform distribution, every probabilistic argument is a counting argument, and Lean checks counting arguments well. We first formalise the three counting principles behind the method — the union bound (first moment), averaging, and Markov's inequality:
/-- **The union bound (first-moment method, counting form).** Let `Ω` be a finite sample space and
`B i` (for `i ∈ S`) a family of "bad" events. If `∑ |B i| < |Ω|` — equivalently, if the bad events
have total probability `< 1` under the uniform distribution — then some outcome `ω` avoids every
bad event. Proof: `|⋃ B i| ≤ ∑ |B i| < |Ω|`, so the union is not everything. -/
theorem exists_avoiding {Ω ι : Type*} [Fintype Ω] [DecidableEq Ω] (S : Finset ι)
(B : ι → Finset Ω) (h : ∑ i ∈ S, (B i).card < Fintype.card Ω) :
∃ ω : Ω, ∀ i ∈ S, ω ∉ B i := by
have hcard : (S.biUnion B).card < (univ : Finset Ω).card :=
lt_of_le_of_lt card_biUnion_le (by simpa using h)
obtain ⟨ω, -, hω⟩ := exists_mem_notMem_of_card_lt_card hcard
exact ⟨ω, fun i hi hωi => hω (mem_biUnion.mpr ⟨i, hi, hωi⟩)⟩/-- **The averaging principle** (a random variable takes a value at least its mean). If
`f` has average at least `c` over a non-empty finite set `s`, then `f(ω) ≥ c` for some `ω ∈ s`.
Proof: otherwise `∑ f < ∑ c = |s| c`. -/
theorem exists_ge_average {Ω : Type*} (s : Finset Ω) (hs : s.Nonempty) (f : Ω → ℝ) (c : ℝ)
(h : s.card * c ≤ ∑ ω ∈ s, f ω) : ∃ ω ∈ s, c ≤ f ω := by
by_contra hcon
simp only [not_exists, not_and, not_le] at hcon
have hlt : ∑ ω ∈ s, f ω < ∑ _ω ∈ s, c := sum_lt_sum_of_nonempty hs hcon
rw [sum_const, nsmul_eq_mul] at hlt
linarith/-- **Markov's inequality, counting form.** For a non-negative function `X` on a finite set and
`a > 0`, `a · #{ω : X ω ≥ a} ≤ ∑ X`; dividing by `|Ω|`, `P(X ≥ a) ≤ E[X]/a`. Proof: drop the
terms with `X < a` and bound each remaining term below by `a`. -/
theorem markov_count {Ω : Type*} [Fintype Ω] (X : Ω → ℝ) (hX : ∀ ω, 0 ≤ X ω) (a : ℝ) :
a * (univ.filter (fun ω => a ≤ X ω)).card ≤ ∑ ω, X ω := by
classical
calc a * (univ.filter (fun ω => a ≤ X ω)).card
= ∑ _ω ∈ univ.filter (fun ω => a ≤ X ω), a := by rw [sum_const, nsmul_eq_mul, mul_comm]
_ ≤ ∑ ω ∈ univ.filter (fun ω => a ≤ X ω), X ω := sum_le_sum fun ω hω => (mem_filter.mp hω).2
_ ≤ ∑ ω, X ω := sum_le_sum_of_subset_of_nonneg (filter_subset _ _) fun ω _ _ => hX ωThen the probability space of Theorem 1: edges of , colourings, and monochromatic sets.
/-- The edges of the complete graph `Kₙ`: the two-element subsets of `Fin n = {0, …, n − 1}`. -/
abbrev Edge (n : ℕ) := {e : Finset (Fin n) // e.card = 2}/-- A red/blue colouring of the edges of `Kₙ` (`true` = red, `false` = blue). There are
`2^{C(n,2)}` of them; the uniform distribution on them is the random colouring of the lesson. -/
abbrev Colouring (n : ℕ) := Edge n → Bool/-- A set `K` of vertices is **monochromatic** for `c` if all edges inside `K` have one colour. -/
def Monochromatic {n : ℕ} (c : Colouring n) (K : Finset (Fin n)) : Prop :=
∃ b : Bool, ∀ e : Edge n, e.1 ⊆ K → c e = bThe counting steps: has edges, a -set spans of them, and therefore a fixed -set is monochromatic in at most colourings — the formal version of :
/-- `Kₙ` has `C(n, 2)` edges. Mathlib: `Fintype.card_finset_len`. -/
theorem card_edge (n : ℕ) : Fintype.card (Edge n) = n.choose 2 := by
simp [Edge, Fintype.card_finset_len]/-- A set of `k` vertices spans (at least — in fact exactly) `C(k, 2)` edges: every two-element
subset of `K` is an edge inside `K`. -/
theorem card_edges_inside {n : ℕ} (K : Finset (Fin n)) :
K.card.choose 2 ≤ Fintype.card {e : Edge n // e.1 ⊆ K} := by
classical
let f : (K.powersetCard 2) → {e : Edge n // e.1 ⊆ K} := fun s =>
⟨⟨s.1, (mem_powersetCard.mp s.2).2⟩, (mem_powersetCard.mp s.2).1⟩
have hf : Function.Injective f := by
intro s t hst
apply Subtype.ext
exact congrArg (fun e : {e : Edge n // e.1 ⊆ K} => e.1.1) hst
have h := Fintype.card_le_of_injective f hf
rwa [Fintype.card_coe, card_powersetCard] at h/-- **Forcing the colour of the edges inside `K`.** At most `2^{C(n,2) − C(k,2)}` colourings give
every edge inside a `k`-set `K` the colour `b`: such a colouring is determined by its values on
the remaining edges. (So the probability is at most `2^{−C(k,2)}`.) -/
theorem card_constant_on_le {n : ℕ} (K : Finset (Fin n)) (b : Bool) :
(univ.filter (fun c : Colouring n => ∀ e : Edge n, e.1 ⊆ K → c e = b)).card
≤ 2 ^ (n.choose 2 - K.card.choose 2) := by
classical
-- restricting to the edges that are not inside `K` is injective
let r : {c : Colouring n // ∀ e : Edge n, e.1 ⊆ K → c e = b} →
({e : Edge n // ¬ e.1 ⊆ K} → Bool) := fun c e => c.1 e.1
have hr : Function.Injective r := by
intro c d hcd
apply Subtype.ext
funext e
by_cases he : e.1 ⊆ K
· rw [c.2 e he, d.2 e he]
· exact congrFun hcd ⟨e, he⟩
have h1 := Fintype.card_le_of_injective r hr
rw [Fintype.card_fun, Fintype.card_bool, Fintype.card_subtype_compl, card_edge,
Fintype.card_subtype] at h1
refine h1.trans (Nat.pow_le_pow_right (by norm_num) (Nat.sub_le_sub_left ?_ _))
exact card_edges_inside Kopen scoped Classical in
/-- **A fixed `k`-set is monochromatic in at most `2 · 2^{C(n,2) − C(k,2)}` colourings** — all red or
all blue. In probability: `P(K monochromatic) ≤ 2^{1 − C(k,2)}`. -/
theorem card_monochromatic_le {n : ℕ} (K : Finset (Fin n)) :
(univ.filter (fun c : Colouring n => Monochromatic c K)).card
≤ 2 * 2 ^ (n.choose 2 - K.card.choose 2) := by
classical
have hsub : univ.filter (fun c : Colouring n => Monochromatic c K) ⊆
univ.filter (fun c : Colouring n => ∀ e : Edge n, e.1 ⊆ K → c e = true) ∪
univ.filter (fun c : Colouring n => ∀ e : Edge n, e.1 ⊆ K → c e = false) := by
intro c hc
obtain ⟨b, hb⟩ := (mem_filter.mp hc).2
cases b
· exact mem_union_right _ (mem_filter.mpr ⟨mem_univ _, hb⟩)
· exact mem_union_left _ (mem_filter.mpr ⟨mem_univ _, hb⟩)
calc _ ≤ _ := card_le_card hsub
_ ≤ _ := card_union_le _ _
_ ≤ 2 ^ (n.choose 2 - K.card.choose 2) + 2 ^ (n.choose 2 - K.card.choose 2) :=
add_le_add (card_constant_on_le K true) (card_constant_on_le K false)
_ = 2 * 2 ^ (n.choose 2 - K.card.choose 2) := by ringThe arithmetic of Theorem 1, and the theorem itself — whenever and :
/-- `(k!)² > 4 · 2ᵏ` for `k ≥ 3` (by induction: `36 > 32`, and each step multiplies the left side
by `(k + 1)² ≥ 16` and the right side by `2`). Equivalently `k! > 2^{1 + k/2}`. -/
theorem factorial_sq_gt {k : ℕ} (hk : 3 ≤ k) : 4 * 2 ^ k < (k.factorial) ^ 2 := by
induction k, hk using Nat.le_induction with
| base => decide
| succ k hk ih =>
rw [Nat.factorial_succ, mul_pow, pow_succ]
have h2 : 2 ≤ (k + 1) ^ 2 := by nlinarith
nlinarith/-- **Erdős's arithmetic**: if `k ≥ 3` and `n² ≤ 2ᵏ`, then `C(n, k) · 2^{1 − C(k,2)} < 1`, i.e.
`2 · C(n, k) < 2^{C(k,2)}`. Proof: `k! · C(n, k) ≤ nᵏ`, so
`(2 C(n,k))² · 2ᵏ = 4 C(n,k)² 2ᵏ < C(n,k)² (k!)² ≤ n^{2k} ≤ 2^{k²} = 2^{2 C(k,2)} · 2ᵏ`,
using `4 · 2ᵏ < (k!)²` and `k² = k(k − 1) + k = 2 C(k,2) + k`. -/
theorem erdos_arithmetic {n k : ℕ} (hk : 3 ≤ k) (hn : n ^ 2 ≤ 2 ^ k) :
2 * n.choose k < 2 ^ k.choose 2 := by
set C := n.choose k with hC
set M := k.choose 2 with hM
rcases Nat.eq_zero_or_pos C with h0 | hpos
· rw [h0]; positivity
-- `k! · C(n, k) ≤ nᵏ`
have hfact : k.factorial * C ≤ n ^ k := by
rw [hC, ← Nat.descFactorial_eq_factorial_mul_choose]
exact Nat.descFactorial_le_pow n k
-- `2 C(k, 2) + k = k²`
have hMk : 2 * M + k = k * k := by
have hdiv : 2 ∣ k * (k - 1) := (Nat.even_mul_pred_self k).two_dvd
have h2M : 2 * M = k * (k - 1) := by
rw [hM, Nat.choose_two_right, Nat.mul_div_cancel' hdiv]
rw [h2M]
obtain ⟨j, rfl⟩ : ∃ j, k = j + 1 := ⟨k - 1, by omega⟩
simp only [Nat.add_sub_cancel]
ring
have h4 := factorial_sq_gt hk
-- chain of inequalities, multiplied through by `2ᵏ`
have hchain : (2 * C) ^ 2 * 2 ^ k < (2 ^ M) ^ 2 * 2 ^ k := by
calc (2 * C) ^ 2 * 2 ^ k = C ^ 2 * (4 * 2 ^ k) := by ring
_ < C ^ 2 * (k.factorial) ^ 2 := by
apply Nat.mul_lt_mul_of_pos_left h4 (by positivity)
_ = (k.factorial * C) ^ 2 := by ring
_ ≤ (n ^ k) ^ 2 := Nat.pow_le_pow_left hfact 2
_ = (n ^ 2) ^ k := by ring
_ ≤ (2 ^ k) ^ k := Nat.pow_le_pow_left hn k
_ = 2 ^ (2 * M + k) := by rw [hMk, ← pow_mul]
_ = (2 ^ M) ^ 2 * 2 ^ k := by ring
have hsq : (2 * C) ^ 2 < (2 ^ M) ^ 2 := Nat.lt_of_mul_lt_mul_right hchain
exact lt_of_pow_lt_pow_left₀ 2 (by positivity) hsq/-- **Erdős's theorem (1947): `R(k, k) > 2^{k/2}`.** If `k ≥ 3` and `n² ≤ 2ᵏ`, some red/blue
colouring of the edges of `Kₙ` has no monochromatic `Kₖ`. Proof (the lesson's, as counting): there
are `C(n, k)` sets of `k` vertices, each monochromatic in at most `2 · 2^{C(n,2) − C(k,2)}` of the
`2^{C(n,2)}` colourings, and `C(n, k) · 2 · 2^{C(n,2) − C(k,2)} < 2^{C(n,2)}` by
`erdos_arithmetic`; the union bound gives a colouring avoiding them all. The proof does not say
which colouring works. -/
theorem erdos_ramsey_lower_bound {n k : ℕ} (hk : 3 ≤ k) (hn : n ^ 2 ≤ 2 ^ k) :
∃ c : Colouring n, ∀ K : Finset (Fin n), K.card = k → ¬ Monochromatic c K := by
classical
set S := (univ : Finset (Fin n)).powersetCard k
set B : Finset (Fin n) → Finset (Colouring n) := fun K =>
univ.filter (fun c : Colouring n => Monochromatic c K)
have hlt : n.choose k * (2 * 2 ^ (n.choose 2 - k.choose 2)) < 2 ^ n.choose 2 := by
rcases le_or_gt k n with hkn | hkn
· have hle : k.choose 2 ≤ n.choose 2 := Nat.choose_le_choose 2 hkn
have hsplit : 2 ^ n.choose 2 = 2 ^ k.choose 2 * 2 ^ (n.choose 2 - k.choose 2) := by
rw [← pow_add, Nat.add_sub_cancel' hle]
rw [hsplit, ← mul_assoc]
exact Nat.mul_lt_mul_of_pos_right (by linarith [erdos_arithmetic hk hn]) (by positivity)
· rw [Nat.choose_eq_zero_of_lt hkn, zero_mul]
positivity
have hsum : ∑ K ∈ S, (B K).card < Fintype.card (Colouring n) := by
calc ∑ K ∈ S, (B K).card ≤ ∑ _K ∈ S, 2 * 2 ^ (n.choose 2 - k.choose 2) := by
apply sum_le_sum
intro K hK
have hKc : K.card = k := (mem_powersetCard.mp hK).2
have := card_monochromatic_le K
rwa [hKc] at this
_ = n.choose k * (2 * 2 ^ (n.choose 2 - k.choose 2)) := by
rw [sum_const, smul_eq_mul, card_powersetCard, card_univ, Fintype.card_fin]
_ < 2 ^ n.choose 2 := hlt
_ = Fintype.card (Colouring n) := by
rw [Fintype.card_fun, Fintype.card_bool, card_edge]
obtain ⟨c, hc⟩ := exists_avoiding S B hsum
refine ⟨c, fun K hK hmono => hc K ?_ ?_⟩
· exact mem_powersetCard.mpr ⟨subset_univ K, hK⟩
· exact mem_filter.mpr ⟨mem_univ c, hmono⟩By contrast, for tiny cases a computer can simply check an explicit colouring:
/-- **An explicit colouring: `R(3, 3) > 5`.** Colour the edge `{i, j}` of `K₅` red when `i` and `j`
are neighbours on the pentagon (`j − i ≡ ±1 mod 5`) and blue otherwise. No three vertices
`a < b < c` span a monochromatic triangle: both colour classes are 5-cycles. Checked by `decide`
over all `C(5, 3) = 10` triangles. For larger `k` no explicit colouring anywhere near Erdős's
bound is known. -/
theorem pentagon_colouring :
let red : Fin 5 → Fin 5 → Bool := fun i j => (j.val + 5 - i.val) % 5 == 1 ||
(j.val + 5 - i.val) % 5 == 4
∀ a b c : Fin 5, a < b → b < c → ¬ (red a b = red b c ∧ red b c = red a c) := by
decideFinally, the analytic inequality at the heart of the Chernoff bound (Theorem 6), from Mathlib:
/-- **`cosh x ≤ e^{x²/2}`**, comparing the Taylor series term by term (`(2k)! ≥ 2ᵏ k!`). For a
uniform random sign `ε = ±1`, `E[e^{λε}] = cosh λ ≤ e^{λ²/2}`, which gives the Chernoff bound
`P(ε₁ + ⋯ + εₙ ≥ a) ≤ e^{−a²/(2n)}`. Mathlib: `Real.cosh_le_exp_half_sq`. -/
theorem cosh_le_exp_half_sq (x : ℝ) : Real.cosh x ≤ Real.exp (x ^ 2 / 2) :=
Real.cosh_le_exp_half_sq xWhat is and is not formalised. Proved here, completely: Erdős's theorem for , (Theorem 1), through the union bound on the uniform space of colourings, with no probability theory beyond counting; the averaging principle and Markov's inequality for counting measure; and by computation. From Mathlib: finite cardinalities and binomial bounds, and . Not formalised: the deletion method, Theorems 3–6 and Corollary 7 as probabilistic statements (Mathlib's measure-theoretic probability can express them, but we have not done so), and the Moser–Tardos analysis. Note that the formal proof, like the human one, does not produce a colouring: it proves an existence statement by counting.
Coin flips, counted
The first experiment tabulates the first-moment and deletion bounds for , simulates random colourings of to see the guarantee in action, and verifies exhaustively that the Paley colouring of has no monochromatic .
"""Random colourings and Ramsey numbers: what the first moment gives.
Colour each edge of K_n red or blue by a fair coin. The expected number of
monochromatic copies of K_k is E(n, k) = C(n, k) 2^(1 - C(k, 2)); when it is
below 1, some colouring has none, so R(k, k) > n (Erdos, 1947). The deletion
method improves this: removing one vertex from each monochromatic K_k leaves
a good colouring on at least n - E(n, k) vertices. We tabulate both bounds,
simulate random colourings of K_6 to see that the probability of having no
monochromatic K_4 really is at least 1 - E(6, 4), and check by exhaustive
search that the Paley graph on 17 vertices (edges between quadratic residue
differences mod 17) has no K_4 and no independent 4-set, an explicit
colouring proving R(4, 4) > 17 - far better than the random bound for such
small k. Exact arithmetic for the bounds, exhaustive search for Paley, and a
seeded simulation (statistical evidence) for the random colourings.
"""
import itertools
import math
import random
from fractions import Fraction
def expected_monochromatic(n, k):
"""E(n, k) = C(n, k) 2^(1 - C(k, 2)) as an exact fraction."""
return Fraction(math.comb(n, k) * 2, 2 ** math.comb(k, 2))
def first_moment_bound(k):
"""Largest n with E(n, k) < 1, so that R(k, k) > n."""
n = k
while expected_monochromatic(n + 1, k) < 1:
n += 1
return n
def deletion_bound(k):
"""max over n of n - floor(E(n, k)): R(k, k) exceeds this number.
Some colouring has at most floor(E) monochromatic K_k; deleting one
vertex from each leaves at least n - floor(E) vertices and none.
"""
best, n = 0, k
while True:
value = n - math.floor(expected_monochromatic(n, k))
if value < best - 5:
return best
best = max(best, value)
n += 1
def random_colouring(n, rng):
"""A dict {(i, j): bool} for i < j, each edge red with probability 1/2."""
return {e: rng.random() < 0.5 for e in itertools.combinations(range(n), 2)}
def count_monochromatic(colouring, n, k):
"""Number of k-subsets all of whose edges have the same colour."""
count = 0
for subset in itertools.combinations(range(n), k):
colours = {colouring[e] for e in itertools.combinations(subset, 2)}
count += len(colours) == 1
return count
def paley_colouring(q):
"""Paley colouring of K_q, q prime = 1 mod 4: red iff i - j is a square."""
squares = {(x * x) % q for x in range(1, q)}
return {(i, j): (j - i) % q in squares
for i, j in itertools.combinations(range(q), 2)}
def main():
print(" k 2^(k/2) first moment: R(k,k) > deletion: R(k,k) >")
for k in range(3, 11):
print(f"{k:>2} {2 ** (k / 2):>7.1f} {first_moment_bound(k):>22}"
f" {deletion_bound(k):>18}")
rng = random.Random(1947)
n, k, trials = 6, 4, 4000
counts = [count_monochromatic(random_colouring(n, rng), n, k)
for _ in range(trials)]
e = expected_monochromatic(n, k)
good = counts.count(0) / trials
margin = 1.96 * math.sqrt(good * (1 - good) / trials)
print(f"Random colourings of K_{n}, {trials} samples (seed 1947):")
print(f" mean number of monochromatic K_{k}: {sum(counts) / trials:.3f}"
f" (exact E = {float(e):.3f})")
print(f" fraction with none: {good:.3f} +- {margin:.3f}"
f" (guaranteed >= 1 - E = {1 - float(e):.3f})")
paley = paley_colouring(17)
mono = count_monochromatic(paley, 17, 4)
print(f"Paley colouring of K_17: {mono} monochromatic K_4 among "
f"{math.comb(17, 4)} sets,")
print(" so R(4,4) > 17 (in fact R(4,4) = 18); the random bound gives > 6.")
print()
print("Epistemic status: the bounds are exact arithmetic and the Paley")
print("check is exhaustive, so both are proofs of what they state; the")
print("simulation is statistical evidence (95% interval shown) about one")
print("seeded run.")
if __name__ == "__main__":
main()The second compares Chebyshev's and Chernoff's bounds with the exact tail of a sum of random signs, and checks Corollary 7 on random set systems.
"""Concentration: Chebyshev versus Chernoff, and balancing sets.
For a sum S of n independent fair signs +-1, Chebyshev's inequality gives
P(S >= a) <= n / a^2, while the Chernoff bound gives P(S >= a) <=
exp(-a^2 / (2n)) - exponentially small. We compare both with the exact
binomial tail and with a seeded simulation for n = 100. Then we use the
Chernoff bound as the lesson does: colour n points red and blue at random;
for each of n given sets, the imbalance |chi(A)| exceeds sqrt(2 n ln 2n) with
probability below 1/n, so with positive probability no set does. For 64
random sets on 64 points we sample random colourings and record how often all
sets are within the bound and the best maximum imbalance found. Exact tails,
seeded simulation (statistical evidence).
"""
import math
import random
def exact_tail(n, a):
"""P(S >= a) for S a sum of n fair +-1 signs (S = 2H - n, H binomial)."""
need = math.ceil((n + a) / 2)
return sum(math.comb(n, h) for h in range(max(need, 0), n + 1)) / 2 ** n
def chebyshev_bound(n, a):
"""Chebyshev: P(S >= a) <= P(|S| >= a) <= n / a^2 (a > 0)."""
return min(1.0, n / a ** 2)
def chernoff_bound(n, a):
"""Chernoff: P(S >= a) <= exp(-a^2 / (2n))."""
return math.exp(-a * a / (2 * n))
def simulate_tail(n, a, trials, rng):
"""Fraction of seeded trials with S >= a, using random bit strings."""
hits = 0
for _ in range(trials):
heads = bin(rng.getrandbits(n)).count("1")
hits += 2 * heads - n >= a
return hits / trials
def random_sets(n_points, n_sets, rng):
"""Each set contains each point independently with probability 1/2."""
return [[i for i in range(n_points) if rng.random() < 0.5]
for _ in range(n_sets)]
def max_imbalance(colouring, sets):
"""max over sets A of |sum of colours (+-1) of the points in A|."""
return max(abs(sum(colouring[i] for i in a)) for a in sets)
def main():
n = 100
rng = random.Random(2024)
print(f"Sum of n = {n} random signs: P(S >= a)")
print(f"{'a':>4} {'exact':>10} {'simulated':>10} {'Chebyshev':>10} "
f"{'Chernoff':>10}")
for a in (10, 20, 30, 40):
sim = simulate_tail(n, a, 20000, rng)
print(f"{a:>4} {exact_tail(n, a):>10.2e} {sim:>10.2e} "
f"{chebyshev_bound(n, a):>10.2e} {chernoff_bound(n, a):>10.2e}")
points = 64
sets = random_sets(points, points, rng)
bound = math.sqrt(2 * points * math.log(2 * points))
trials = 500
maxima = sorted(max_imbalance([rng.choice((-1, 1)) for _ in range(points)],
sets) for _ in range(trials))
within = sum(m <= bound for m in maxima)
print(f"Balancing {points} random sets on {points} points:")
print(f" bound sqrt(2n ln 2n) = {bound:.1f}; random colourings within "
f"it: {within}/{trials}")
print(f" maximum imbalance: median {maxima[trials // 2]}, "
f"best {maxima[0]}, worst {maxima[-1]}")
print()
print("Epistemic status: the tails are exact; the simulated columns are")
print("statistical evidence from seeded runs. The bounds themselves are")
print("theorems (Chebyshev; Chernoff via cosh x <= exp(x^2/2)).")
if __name__ == "__main__":
main()The third builds a random -CNF formula satisfying the hypothesis of the symmetric local lemma and runs the Moser–Tardos algorithm: it finds a satisfying assignment after a handful of resamplings, while the local lemma itself only guarantees that a uniformly random assignment succeeds with probability at least about .
"""The algorithmic local lemma: Moser and Tardos's resampling algorithm.
A k-CNF formula has clauses of k literals; under a uniformly random
assignment each clause fails with probability p = 2^-k. If every clause
shares variables with at most d others and e p (d + 1) <= 1, the Lovasz local
lemma says the formula is satisfiable - but its proof gives no algorithm,
and the probability that a random assignment works can be exponentially
small. Moser and Tardos (2010) showed that the obvious algorithm is fast:
start at random, and while some clause is violated, resample its variables.
The expected number of resamplings is at most m / d for m clauses. We build a
random 5-CNF instance with dependency degree at most 10 (so e p (d+1) < 1),
run the algorithm from 30 seeds, check the answers, and compare the number of
resamplings with the bound m / d and with naive rejection sampling. Seeded
simulation: statistical evidence about one instance, with every output
assignment verified exactly.
"""
import math
import random
def neighbours(clauses, index, occurrences):
"""Indices of the other clauses sharing a variable with clause index."""
out = set()
for var, _ in clauses[index]:
out |= occurrences[var]
out.discard(index)
return out
def build_instance(n_vars, n_clauses, k, max_degree, rng, max_tries=20000):
"""Random k-CNF; a clause is kept only if all dependency degrees stay <= max_degree.
A clause is a tuple of (variable, wanted_value) pairs; it is satisfied
when at least one variable has its wanted value.
"""
clauses, occurrences = [], [set() for _ in range(n_vars)]
for _ in range(max_tries):
if len(clauses) == n_clauses:
break
vars_ = rng.sample(range(n_vars), k)
clause = tuple((v, rng.random() < 0.5) for v in vars_)
clauses.append(clause)
new = len(clauses) - 1
for v in vars_:
occurrences[v].add(new)
touched = neighbours(clauses, new, occurrences) | {new}
if any(len(neighbours(clauses, c, occurrences)) > max_degree
for c in touched):
for v in vars_:
occurrences[v].discard(new)
clauses.pop()
return clauses
def max_dependency_degree(clauses, n_vars):
"""The largest number of other clauses any clause shares a variable with."""
occurrences = [set() for _ in range(n_vars)]
for i, clause in enumerate(clauses):
for v, _ in clause:
occurrences[v].add(i)
return max(len(neighbours(clauses, i, occurrences))
for i in range(len(clauses)))
def satisfied(clause, assignment):
"""True if some literal of the clause holds."""
return any(assignment[v] == want for v, want in clause)
def moser_tardos(clauses, n_vars, rng):
"""Resample violated clauses until none is left; return (assignment, steps)."""
assignment = [rng.random() < 0.5 for _ in range(n_vars)]
steps = 0
while True:
bad = [c for c in clauses if not satisfied(c, assignment)]
if not bad:
return assignment, steps
for v, _ in rng.choice(bad):
assignment[v] = rng.random() < 0.5
steps += 1
def naive_successes(clauses, n_vars, tries, rng):
"""How many of `tries` uniformly random assignments satisfy every clause."""
hits = 0
for _ in range(tries):
bits = rng.getrandbits(n_vars)
hits += all(any(((bits >> v) & 1) == want for v, want in clause)
for clause in clauses)
return hits
def main():
k, d, n_vars = 5, 10, 400
rng = random.Random(2010)
clauses = build_instance(n_vars, 150, k, d, rng)
m = len(clauses)
deg = max_dependency_degree(clauses, n_vars)
p = 2.0 ** -k
print(f"Random {k}-CNF: {n_vars} variables, {m} clauses, "
f"max dependency degree {deg}")
print(f" LLL condition e p (d+1) = {math.e * p * (deg + 1):.3f} <= 1")
runs = [moser_tardos(clauses, n_vars, random.Random(seed))
for seed in range(30)]
ok = all(all(satisfied(c, a) for c in clauses) for a, _ in runs)
steps = sorted(s for _, s in runs)
print(f"Moser-Tardos from 30 seeds: all outputs satisfy every clause: {ok}")
print(f" resamplings: mean {sum(steps) / len(steps):.1f}, "
f"max {steps[-1]}; bound on the mean m/d = {m / deg:.1f}")
tries = 2000
hits = naive_successes(clauses, n_vars, tries, rng)
print(f"Naive: {hits} of {tries} uniformly random assignments satisfy "
"the formula;")
print(f" the LLL only guarantees probability >= (1 - 1/(d+1))^m = "
f"{(1 - 1 / (deg + 1)) ** m:.1e}")
print()
print("Epistemic status: every output assignment is verified exactly;")
print("the step counts and the naive success rate are statistical")
print("evidence about one seeded instance. The bound m/d on the expected")
print("number of resamplings is Moser and Tardos's theorem.")
if __name__ == "__main__":
main()Exercises
1. The probabilistic method
Warm-upHumanColour the edges of red or blue by independent fair coin flips. What is the expected number of monochromatic triangles?
2. The probabilistic method
Warm-upHumanFor a random colouring of , the expected number of monochromatic 's is . What can we conclude?
3. The probabilistic method
CoreHumanWhat is the largest for which the first-moment condition holds? (It proves .)
4. The probabilistic method
CoreHumanIn the proof that every graph with edges has a cut of size , we write with if edge is cut, and conclude . The are not mutually independent (the three edges of a triangle cannot all be cut). Why is the conclusion still valid?
5. The probabilistic method
CoreHumanIn Erdős's proof of Theorem 3, with and , why do we delete a vertex from each short cycle instead of asking that the random graph have no short cycles at all?
6. The probabilistic method
StretchHumanIn a -CNF formula (every clause has literals on distinct variables), each clause shares variables with at most other clauses. What is the largest for which the symmetric Lovász local lemma () guarantees that the formula is satisfiable?
7. The probabilistic method
CoreHumanLet be a sum of independent random signs . Which is the Chernoff bound (Theorem 6) for ?
8. The probabilistic method
CoreFormalWith Colouring n the red/blue colourings of the edges of and Monochromatic c K meaning that all edges inside the vertex set K have the same colour under c, which Lean statement says ?
9. The probabilistic method
StretchComputationalWrite expected_mono(n, k) returning as an exact Fraction, and first_moment_bound(k) returning the largest with expected_mono(n, k) < 1 (so that ).
Common misconceptions
Misconception
"A probabilistic existence proof tells us how to build the object efficiently." Often it does not. Erdős's proof shows that most colourings of with have no monochromatic , but no explicit colouring anywhere near this size is known, and checking a given colouring takes time about . When good objects are plentiful, random sampling is a fine randomised algorithm — but it is not a construction, and verifying the output may be infeasible. Sometimes derandomisation succeeds (conditional expectations for cuts; Moser–Tardos for the local lemma), and sometimes, as for Ramsey graphs, it is a famous open problem.
Misconception
"Linearity of expectation needs independence." It does not: for any random variables with finite expectations. In the max-cut example the events "edge is cut" are dependent, and in Theorem 1 the events " is monochromatic" overlap heavily; linearity is exactly what lets us ignore these dependencies. Independence is needed for variances of sums and for multiplying probabilities.
Misconception
"If then with high probability." Not without concentration: if with probability and otherwise, then but . The second-moment method (Theorem 4) supplies the missing condition . Conversely, shows but need not show that it is close to .
Misconception
"Probabilistic proofs are heuristic, or only true 'with high probability'." The conclusions are ordinary, certain theorems — "there exists a colouring with no monochromatic " — proved by computing probabilities on a precisely defined space. On finite spaces they are counting arguments, as the Lean proof shows. (Heuristic probabilistic models, such as Cramér's model of the primes, are a different thing and must be labelled as such.)
Viewpoints
Combinatorics— Weighted counting and double counting
Every argument on a finite uniform space is double counting: "" is the identity , and Theorem 1 says the right-hand side is less than the number of colourings. Non-uniform distributions such as are weighted counts, and the weights are a tuning parameter: Theorem 3 works only because balances short cycles against independent sets. The method interacts with extremal combinatorics everywhere: the Kővári–Sós–Turán bounds for bipartite Turán numbers are matched (for some graphs) by random algebraic constructions, the semi-random method of Rödl ("nibble") gives near-perfect packings and designs, and Kim (1995) used it to determine up to a constant factor, (upper bound by Ajtai, Komlós and Szemerédi, 1980). See extremal and additive combinatorics.
Probability— Random structures as the subject
What began as a proof technique became a field: the study of typical properties of random graphs, random matrices and random formulas. Thresholds (Theorem 4) are a general phenomenon — every monotone graph property has a threshold (Bollobás and Thomason, 1987), and the "expectation threshold" conjecture of Kahn and Kalai was proved by Park and Pham (2022). Concentration inequalities (Chernoff, Azuma, Talagrand) show that complicated functions of many independent variables — the chromatic number of , the length of the longest increasing subsequence — are sharply concentrated. The phase transition of at resembles percolation in statistical physics (see random structures and stochastic processes).
Computation— Randomness, derandomisation and pseudorandomness
In computer science the probabilistic method is everywhere: random algorithms (randomised rounding of linear programs, Raghavan and Thompson, 1987; primality testing; hashing), and the question of when randomness can be removed. Conditional expectations with pessimistic estimators (Raghavan, 1988) derandomise many Chernoff-bound arguments; Moser and Tardos derandomised the local lemma in the sense of efficient randomised algorithms, and later work made it deterministic in many cases. The harder goal — explicit objects as good as random ones — connects to complexity theory: explicit Ramsey graphs are closely related to randomness extractors, and expander graphs and error-correcting codes with random-like properties now have explicit constructions. Whether every efficient randomised algorithm can be derandomised (P = BPP) is open, though widely believed (see computational complexity).
Geometry— Random projections and high-dimensional geometry
The Johnson–Lindenstrauss lemma (1984): any points in a Euclidean space can be mapped into with so that all pairwise distances change by a factor at most . The proof is the probabilistic method: a random linear projection works with positive probability, because the length of a projected vector is sharply concentrated (a Chernoff-type bound for sums of squared Gaussians) and there are only distances to control. More generally, concentration of measure on high-dimensional spheres (Lévy; Milman) says that a Lipschitz function is almost constant on most of the sphere, which gives Dvoretzky's theorem — every high-dimensional convex body has almost-spherical sections of dimension about — by choosing a random subspace. In high dimensions, random choices are the source of most good geometric configurations.
Logic— Zero–one laws
For a property expressible in first-order logic of graphs (quantifiers over vertices, adjacency and equality), the probability that has the property tends to or (Glebskii, Kogan, Liogon'kii and Talanov, 1969; Fagin, 1976). The proof is model-theoretic: the "extension axioms" — for all disjoint finite sets there is a vertex adjacent to all of and none of — each hold with high probability by a first-moment computation, and together they axiomatise a complete theory, that of the countable random graph (Rado graph). So "having a triangle" has limiting probability , while non-first-order properties such as "having an even number of edges" can have other limits (). See model theory.
History and global context
- Tibor Szele (1943) used random tournaments to show that some tournament has at least Hamiltonian paths. Claude Shannon's random coding argument (1948) proved the existence of codes achieving channel capacity by averaging over random codes — a cornerstone of information theory and an early masterpiece of the method.
- Paul Erdős (1947) proved , and (1959) the existence of graphs of large girth and chromatic number; with Alfréd Rényi (1959–60) he founded the theory of random graphs. Erdős's many problems, often with cash prizes, kept the method at the centre of combinatorics.
- Herman Chernoff (1952) introduced the exponential-moment bounds now named after him (related bounds go back to Bernstein); Wassily Hoeffding (1963) gave the general bounded-variable form. László Lovász and Erdős (1975) proved the local lemma, published in a paper on hypergraph colouring; Joel Spencer (1975) applied it to Ramsey numbers and (1985) proved that six standard deviations suffice for discrepancy.
- Noga Alon and Spencer's The Probabilistic Method (1992) made the subject a standard graduate course. Jeong Han Kim (1995) determined up to a constant factor with the semi-random method; Robin Moser (2009) and Moser and Gábor Tardos (2010) made the local lemma algorithmic; Nikhil Bansal (2010) did the same for Spencer's discrepancy theorem.
- On Ramsey numbers: Greenwood and Gleason (1955) found ; Geoffrey Exoo (1989) showed ; Vigleik Angeltveit and Brendan McKay (2024) showed with large computations; Marcelo Campos, Simon Griffiths, Robert Morris and Julian Sahasrabudhe (2023) gave the first exponential improvement of the Erdős–Szekeres upper bound.
Further reading
- Noga Alon and Joel H. Spencer, The Probabilistic Method (1992; 4th ed. 2016) — the standard text, with Erdős's theorems, the local lemma, concentration, random graphs and derandomisation.
- Joel Spencer, Ten Lectures on the Probabilistic Method (1987; 2nd ed. 1994) — short, sparkling lectures.
- Michael Molloy and Bruce Reed, Graph Colouring and the Probabilistic Method (2002) — the local lemma and concentration in action.
- Béla Bollobás, Random Graphs (1985; 2nd ed. 2001), and Svante Janson, Tomasz Łuczak and Andrzej Ruciński, Random Graphs (2000) — thresholds, phase transitions and the giant component.
- Michael Mitzenmacher and Eli Upfal, Probability and Computing (2005) — the method from the algorithmic side, including Chernoff bounds and the Moser–Tardos algorithm (2nd ed., 2017).