Monocurl Essays
Series Download

The probabilistic method: Ramsey numbers by coin flips

Six party guests always include three mutual friends or three mutual strangers. For larger parties, the best lower bounds come from coloring at random.

24 min·Early college·

AssumesThe pigeonhole principle: obvious, and surprisingly strongPermutations and combinations: counting without listingWhat probability means: counting equally likely outcomes

Each pair of six party guests is made friends (blue) or strangers (orange) by a coin flip. Once all fifteen pairs are decided, three guests who are all friends or all strangers can be found, as happens for every outcome of the flips.
Monocurl source
let AZ = raz(41)
let TRI = find_tri(6, AZ)
let C0 = [-1.55, 0, 0]
let P = pairs(6)
let Party = |s, h| {
    var parts = [Region(map(TRI, |v| ring(6, v, C0, 1.7)), lerp(PAPER, tint(ROSE, 0.25), h))]
    for (p in [0, 1]) {
        for (idx in range(0, 15)) {
            let e = P[idx]
            let intri = (e[0] in TRI) and (e[1] in TRI)
            if (intri == p) {
                let col = EC[e in AZ]
                let base = lerp(MIST, col, clamp(0, s - idx, 1))
                parts .= Seg(ring(6, e[0], C0, 1.7), ring(6, e[1], C0, 1.7), [lerp(base, tint(col, 0.3), h), base][intri], [4, 4 + 2 * h][intri])
            }
        }
    }
    parts .= Guests(6, C0, 1.7, [[], TRI][h > 0.5])
    return parts
}
mesh party = Party(s: 0, h: 0)
mesh words = [
    center{[2.3, 1.45, 0]} Cap("6 guests, 15 pairs", 0.85, INK),
    center{[2.3, 0.75, 0]} Cap("blue: friends", 0.8, AZURE),
    center{[2.3, 0.25, 0]} Cap("orange: strangers", 0.8, EMBER)
]
mesh verdict = []

slide "flip"
    play Wait(0.5)
    party.s = 15
    play Lerp(5, [&party], linear)
    party.h = 1
    play Lerp(0.8, [&party])
    verdict = [
        center{[2.3, -0.85, 0]} Cap(str_join(map(TRI, |v| NAMES[v]), ", "), 0.9, ROSE),
        center{[2.3, -1.4, 0]} Cap(["all strangers", "all friends"][[TRI[0], TRI[1]] in AZ], 0.85, ROSE)
    ]
    play Fade(0.6, [&verdict])
    play Wait(2)

Uses the shared definitions for this lesson's figures.

You are hosting a party with five guests. You hope for some level of familiarity, but also some level of strangeness between the guests. Specifically, you hope that no three guests all know each other beforehand, and that no three are all mutual strangers. Is there a guest list like that? And if there is one for five guests, is there one for six?

The first question yields to a few minutes of trial and error. The second is a different kind of problem, because among six people there are $2^{15} = 32{,}768$ ways to decide who knows whom, and for bigger versions of the question the count outruns every computer. We will settle both by proof. Then we turn to the bigger versions, where the best known way to produce a good arrangement is to flip a coin for every pair and prove that the coins cannot fail every time.

Graphs and colorings

To make the problem mathematical, represent it as a graph. Each person is a vertex, and a line is drawn between every pair. Color the line blue if the two people are friends and orange if they are strangers. Below is a first attempt for five guests, colored without much thought. It fails: $A$, $B$ and $E$ all know each other.

A first attempt at the party of five. Blue edges join friends and orange edges join strangers. The three guests A, B and E are joined by three blue edges, so they are three mutual friends and the attempt fails.
A first attempt at the party of five. Blue edges join friends and orange edges join strangers. The three guests A, B and E are joined by three blue edges, so they are three mutual friends and the attempt fails.
Monocurl source
let AZ = [[0, 1], [1, 4], [0, 4], [2, 3], [1, 3]]
let TRI = find_tri(5, AZ)
let C0 = [-1.6, -0.1, 0]
mesh graph = [
    Edges(5, C0, 1.7, AZ, rest(5, AZ), TRI),
    Guests(5, C0, 1.7, TRI)
]
mesh words = [
    center{[2.25, 1.3, 0]} Cap("blue: friends", 0.8, AZURE),
    center{[2.25, 0.8, 0]} Cap("orange: strangers", 0.8, EMBER),
    center{[2.25, -0.3, 0]} Cap(str_join(map(TRI, |v| NAMES[v]), ", "), 0.9, ROSE),
    center{[2.25, -0.85, 0]} Cap(["three mutual strangers", "three mutual friends"][[TRI[0], TRI[1]] in AZ], 0.8, ROSE)
]

Uses the shared definitions for this lesson's figures.

The number $\binom{n}{2} = \frac{n(n-1)}{2}$ counts the ways to choose 2 vertices from $n$. A blue triangle is three mutual friends and an orange triangle is three mutual strangers, so the host wants a 2-coloring of $K_5$ with no monochromatic triangle. I will call such a coloring valid.

Building up: small cases

It’s instructive to start with smaller examples. With three people the arrangement is not difficult to construct. Color $AB$ blue, then $AC$ blue, and we’re forced to color $BC$ orange to avoid a blue triangle. For four, we can reuse that coloring and try to color the three new edges.

  1. With three guests, color AB and AC blue. One edge is left.
  2. BC must be orange, or A, B, C would be three mutual friends. The triangle now has both colors.
  3. A fourth guest D arrives. Keep the old colors. Three new edges need a color.
  4. Color BD blue and AD, CD orange. Each of the four triangles has both colors, so four guests work too.
Valid colorings for three guests and then four. The coloring of the triangle A, B, C is kept when D arrives, and the three new edges are colored so that each of the four triangles has both colors.
Monocurl source
let C3 = [-2.2, 0.1, 0]
let C4 = [1.6, 0.45, 0]
mesh e3 = []
mesh e4 = []
mesh n3 = []
mesh n4 = []
mesh lab = []
mesh legend = []

slide "With three guests, color AB and AC blue. One edge is left."
    legend = [
        center{[1.6, 0.5, 0]} Cap("blue: friends", 0.85, AZURE),
        center{[1.6, -0.1, 0]} Cap("orange: strangers", 0.85, EMBER)
    ]
    e3 = Edges(3, C3, 1.45, [[0, 1], [0, 2]], [])
    n3 = Guests(3, C3, 1.3)
    lab = [center{[-2.2, -1.42, 0]} Math("n = 3", 0.9, INK)]
    play Fade(0.6)

slide "BC must be orange, or A, B, C would be three mutual friends. The triangle now has both colors."
    e3 = Edges(3, C3, 1.45, [[0, 1], [0, 2]], [[1, 2]])
    lab .= center{[-2.2, -1.9, 0]} Cap("no one-color triangle", 0.74, LEAF)
    play Fade(0.6)

slide "A fourth guest D arrives. Keep the old colors. Three new edges need a color."
    legend = []
    play Fade(0.3, [&legend])
    e4 = Edges(4, C4, 1.25, [[0, 1], [0, 2]], [[1, 2]])
    n4 = Guests(4, C4, 1.25)
    lab .= center{[1.6, -1.42, 0]} Math("n = 4", 0.9, INK)
    play Fade(0.6)

slide "Color BD blue and AD, CD orange. Each of the four triangles has both colors, so four guests work too."
    e4 = Edges(4, C4, 1.25, [[0, 1], [0, 2], [1, 3]], [[1, 2], [0, 3], [2, 3]])
    lab .= center{[1.6, -1.9, 0]} Cap("no one-color triangle", 0.74, LEAF)
    play Fade(0.6)

Uses the shared definitions for this lesson's figures.

Pause and try

Find a valid coloring of $K_5$ before reading on. A hint from the failed attempt above: $B$ had three blue edges there. Try to give every vertex two edges of each color.

Show answerHide answer

Place the five vertices at the corners of a regular pentagon. Color the five sides orange and the five diagonals blue. Every vertex then has two orange and two blue edges, and the check that no triangle is monochromatic is the proof below.

For five, extending the four-guest coloring by hand works, but the pentagon coloring is more regular, which lets us check all ten triangles with one argument.

The pentagon coloring of five guests, with orange sides and blue diagonals, beside all ten of its triangles. Each triangle contains at least one edge of each color, so no three guests are all friends or all strangers.
The pentagon coloring of five guests, with orange sides and blue diagonals, beside all ten of its triangles. Each triangle contains at least one edge of each color, so no three guests are all friends or all strangers.
Monocurl source
let AZ = [[0, 2], [0, 3], [1, 3], [1, 4], [2, 4]]
let C0 = [-2.15, 0.05, 0]
let TRIS = block {
    for (i in range(0, 5)) {
        for (j in range(i + 1, 5)) {
            for (k in range(j + 1, 5)) {
                . [i, j, k]
            }
        }
    }
}
let slot = |m| [0.3 + 0.78 * (m - 5 * (m // 5)), 0.95 - 1.6 * (m // 5), 0]
let Mini = |m| {
    let t = TRIS[m]
    let c = slot(m)
    return [
        map(range(0, 5), |v| Pt(ring(5, v, c, 0.26), MIST, 0.04)),
        map([[t[0], t[1]], [t[1], t[2]], [t[0], t[2]]], |e| Seg(ring(5, e[0], c, 0.26), ring(5, e[1], c, 0.26), EC[e in AZ], 3.5)),
        center{[c[0], c[1] - 0.6, 0]} Cap(str_join(map(t, |v| NAMES[v])), 0.7, SLATE)
    ]
}
mesh graph = [
    Edges(5, C0, 1.6, AZ, rest(5, AZ)),
    Guests(5, C0, 1.6)
]
mesh minis = map(range(0, 10), |m| Mini(m))
mesh words = [
    center{[1.86, 1.8, 0]} Note(str_join(["all ", to_string(len(TRIS)), " triangles"]), 0.76),
    center{[1.86, -1.85, 0]} Cap(["a triangle has one color", "each has both colors"][len(find_tri(5, AZ)) == 0], 0.8, [ROSE, LEAF][len(find_tri(5, AZ)) == 0])
]

Uses the shared definitions for this lesson's figures.

So the answer to the party question is yes: with five guests a valid arrangement exists.

The wall at six

It is natural to try to keep going. Based on the past it might seem that there is an inductive argument: take a valid coloring on $n - 1$ vertices and extend it to $n$. But once we get to $n = 6$, no matter what you try, you can’t avoid a monochromatic triangle. Here are 24 colorings of $K_6$ chosen by coin flips. A search finds a monochromatic triangle in every one.

Eight copies of the complete graph on six vertices, each colored by coin flips three times over. In every one of the 24 random colorings a search finds a triangle whose three edges have one color, and that triangle is shaded.
Monocurl source
let WAZ = map(range(0, 24), |g| raz(g + 1))
let WTRI = map(WAZ, |az| find_tri(6, az))
let ctr = |m| [-2.7 + 1.8 * (m - 4 * (m // 4)), 1.02 - 2.04 * (m // 4), 0]
let MiniK = |c, az, tri, a, h| {
    let r = 0.8
    var parts = [fill{[ROSE[0], ROSE[1], ROSE[2], 0.25 * a * h]} stroke{[1, 1, 1, 0], 0} Polygon(map(tri, |v| ring(6, v, c, r)))]
    for (p in [0, 1]) {
        for (e in pairs(6)) {
            let intri = (e[0] in tri) and (e[1] in tri)
            if (intri == p) {
                let col = EC[e in az]
                parts .= stroke{[col[0], col[1], col[2], a * [1 - 0.8 * h, 1][intri]], [3, 3 + 2.5 * h][intri]} Line(ring(6, e[0], c, r), ring(6, e[1], c, r))
            }
        }
    }
    return parts
}
let Wall = |s| {
    let s2 = min(s, 2.999)
    let rd = to_int(floor(s2))
    let f = s2 - rd
    let a = clamp(0, f / 0.1, 1) * clamp(0, (1 - f) / 0.08 + (rd == 2), 1)
    let h = clamp(0, (f - 0.38) / 0.12, 1)
    return map(range(0, 8), |m| MiniK(ctr(m), WAZ[rd * 8 + m], WTRI[rd * 8 + m], a, h))
}
mesh wall = Wall(s: 0)
mesh dots = map(range(0, 8), |m| map(range(0, 6), |v| Pt(ring(6, v, ctr(m), 0.8), SLATE, 0.075)))

slide "wall"
    wall.s = 3
    play Lerp(10.5, [&wall], linear)
    play Wait(1.3)

Uses the shared definitions for this lesson's figures.

Twenty-four failures out of 32,768 colorings are evidence and not a proof. Checking the rest by machine would settle six guests and teach us nothing about seven, so let us look for a reason. The earlier hint pointed at it: trouble started at a vertex with three edges of one color.

Pause and try

In a 2-coloring of $K_6$, pick one vertex $F$. Five edges leave it. At least how many of them must share a color, and why?

Show answerHide answer

Three. If each color appeared at most twice, $F$ would have at most 4 edges. This is the pigeonhole principle: 5 edges in 2 colors put at least $\lceil 5/2 \rceil = 3$ in one color.

  1. Take any coloring and any guest F. Of the five edges at F, at least three share a color. Say FA, FB and FC are blue.
  2. If AB were blue, then F, A and B would be three mutual friends.
  3. The same goes for BC and AC. To avoid a blue triangle, all three edges among A, B, C must be orange.
  4. But then A, B and C are three mutual strangers. Either way a one-color triangle appears.
The proof that six guests always contain a one-color triangle. Three edges of one color leave the vertex F. If any edge among their far ends has that color it closes a triangle with F, and if none does, the far ends form a triangle of the other color.
Monocurl source
let C0 = [-1.5, 0, 0]
let FAN = [[0, 5], [1, 5], [2, 5]]
mesh graph = []
mesh people = []
mesh words = []

slide "Take any coloring and any guest F. Of the five edges at F, at least three share a color. Say FA, FB and FC are blue."
    graph = Edges(6, C0, 1.7, FAN, [])
    people = Guests(6, C0, 1.7)
    words = [
        center{[2.3, 0.9, 0]} Cap("5 edges at F", 0.82, INK),
        center{[2.3, 0.3, 0]} Cap("3 share a color", 0.82, AZURE)
    ]
    play Fade(0.6)

slide "If AB were blue, then F, A and B would be three mutual friends."
    words = []
    play Fade(0.3, [&words])
    graph = Edges(6, C0, 1.7, [[0, 5], [1, 5], [2, 5], [0, 1]], [], [0, 1, 5])
    people = Guests(6, C0, 1.7, [0, 1, 5])
    words = [center{[2.3, 0.6, 0]} Cap("blue triangle F, A, B", 0.82, ROSE)]
    play Fade(0.6)

slide "The same goes for BC and AC. To avoid a blue triangle, all three edges among A, B, C must be orange."
    words = []
    play Fade(0.3, [&words])
    graph = Edges(6, C0, 1.7, FAN, [[0, 1], [1, 2], [0, 2]])
    people = Guests(6, C0, 1.7)
    words = [center{[2.3, 0.6, 0]} Cap("AB, BC, AC orange", 0.82, EMBER)]
    play Fade(0.6)

slide "But then A, B and C are three mutual strangers. Either way a one-color triangle appears."
    words = []
    play Fade(0.3, [&words])
    graph = Edges(6, C0, 1.7, FAN, [[0, 1], [1, 2], [0, 2]], [0, 1, 2])
    people = Guests(6, C0, 1.7, [0, 1, 2])
    words = [center{[2.3, 0.6, 0]} Cap("orange triangle A, B, C", 0.82, ROSE)]
    play Fade(0.6)

Uses the shared definitions for this lesson's figures.

The proof used nothing about the coloring except that $F$ has five edges. With five guests a vertex has four edges, which can split two and two, and that is the room the pentagon uses.

Ramsey numbers

Three mutual friends or three mutual strangers are forced at six guests and not at five. The same question can be asked with other clique sizes.

Read the definition against what we did. To show $R(s,t) \le n$ you must argue about every coloring of $K_n$, as in the proof for six. To show $R(s,t) > n$ it is enough to exhibit one coloring of $K_n$ with neither clique, as the pentagon does for $n = 5$. Together the two theorems above say

$$ R(3, 3) = 6. $$

If every coloring of $K_n$ contains one of the cliques, so does every coloring of a larger $K_m$, because $n$ of its vertices already carry a coloring of $K_n$. So $R(s,t)$ is a threshold: below it some coloring avoids both cliques, and from it onward none does.

A priori these numbers aren’t even well defined, since nothing so far says that any $n$ at all works for, say, $s = t = 10$. In 1930 Frank Ramsey proved that such an $n$ always exists. A few years later, Erdős and Szekeres found a short argument that also gives an explicit upper bound. It is the proof for six guests with the numbers replaced by letters.

A timeline of bounds on Ramsey numbers. Ramsey proved in 1930 that they are finite, Erdős and Szekeres gave the binomial upper bound in 1935, Erdős proved an exponential lower bound by random coloring in 1947, Greenwood and Gleason found R(4,4) = 18 in 1955, Campos and coauthors lowered the base of the upper bound below 4 in 2023, and in 2023 Angeltveit and McKay showed that R(5,5) is at most 46.
A timeline of bounds on Ramsey numbers. Ramsey proved in 1930 that they are finite, Erdős and Szekeres gave the binomial upper bound in 1935, Erdős proved an exponential lower bound by random coloring in 1947, Greenwood and Gleason found R(4,4) = 18 in 1955, Campos and coauthors lowered the base of the upper bound below 4 in 2023, and in 2023 Angeltveit and McKay showed that R(5,5) is at most 46.
Monocurl source
let Event = |x, side, year, who, tex, col| [
    Seg([x, 0, 0], [x, side * 0.32, 0], col, 3),
    Pt([x, 0, 0], col, 0.11),
    center{[x, side * 0.62, 0]} Math(year, 0.9, col),
    center{[x, side * 1.12, 0]} Cap(who, 0.76, INK),
    center{[x, side * 1.68, 0]} Math(tex, 0.78, col)
]
mesh line = Tip([-3.6, 0, 0], [3.7, 0, 0], SLATE, 3)
mesh events = [
    Event(-3.0, 1, "1930", "Ramsey", "R(s,t) \text{ is finite}", SLATE),
    Event(-1.75, -1, "1935", "Erdős, Szekeres", "R(k,k) \le \binom{2k-2}{k-1}", PLUM),
    Event(-0.5, 1, "1947", "Erdős", "R(k,k) > 2^{k/2}", LEAF),
    Event(0.75, -1, "1955", "Greenwood, Gleason", "R(4,4) = 18", SLATE),
    Event(1.9, 1, "2023", "Campos et al.", "R(k,k) \le (4 - \varepsilon)^k", PLUM),
    Event(2.9, -1, "2023", "Angeltveit, McKay", "R(5,5) \le 46", PLUM)
]

Uses the shared definitions for this lesson's figures.

Upper bounds, then, come from an argument about every coloring. Lower bounds need colorings that avoid large monochromatic cliques, and for a while those came from increasingly clever constructions. The simple ones grow only like a power of $k$ (see Problem 4). Then in 1947 Erdős published an argument only a few lines long that gives a lower bound growing exponentially in $k$, and it constructs nothing.

A random coloring

The core idea behind Erdős’s method is probabilistic instead of constructive. We start with a completely random coloring and ask for the probability that it contains a monochromatic clique of size $k$. If that probability is less than 1, then some coloring contains none.

Try it first where everything can be counted: triangles in $K_4$. Flip a fair coin for each of the 6 edges. The sample space is the set of $2^6 = 64$ colorings, all equally likely. A particular triangle is monochromatic when its 3 edges are all blue or all orange, which fixes those edges in one of 2 ways and leaves the other 3 edges free. That is $2 \cdot 2^3 = 16$ colorings, a probability of $\frac{16}{64} = \frac14$.

Pause and try

$K_4$ has four triangles, and each is monochromatic with probability $\frac14$. Is the probability that at least one of them is monochromatic equal to $4 \cdot \frac14 = 1$? Decide by finding one coloring of $K_4$ with no monochromatic triangle.

Show answerHide answer

It is less than 1: the valid coloring of four guests found earlier is one of the 64 outcomes. Adding the four probabilities counts a coloring once for every monochromatic triangle it has, so colorings with several are counted several times. The figure below does the exact count.

All 64 two-colorings of the complete graph on four vertices, sorted by how many of the four triangles are monochromatic. Eighteen colorings have none, 32 have one, 12 have two and 2 have all four, so 46 of the 64 contain a monochromatic triangle while the four separate probabilities add up to 1.
All 64 two-colorings of the complete graph on four vertices, sorted by how many of the four triangles are monochromatic. Eighteen colorings have none, 32 have one, 12 have two and 2 have all four, so 46 of the 64 contain a monochromatic triangle while the four separate probabilities add up to 1.
Monocurl source
let bit = |m, i| to_int(mod(m // (2 ^ i), 2))
let TR = [[0, 1, 3], [0, 2, 4], [1, 2, 5], [3, 4, 5]]
let mono = |m| len(filter(TR, |t| mod(bit(m, t[0]) + bit(m, t[1]) + bit(m, t[2]), 3) == 0))
var ord = []
for (c in [0, 1, 2, 4]) {
    for (m in range(0, 64)) {
        if (mono(m) == c) {
            ord .= m
        }
    }
}
let ORD = ord
let nwith = |c| len(filter(range(0, 64), |m| mono(m) == c))
let SH = [tint(LEAF, 0.32), tint(ROSE, 0.13), tint(ROSE, 0.36), tint(ROSE, 0.36), tint(ROSE, 0.65)]
let P4 = pairs(4)
let corner = |v, c| [c[0] + [-0.13, 0.13, 0.13, -0.13][v], c[1] + [0.13, 0.13, -0.13, -0.13][v], 0]
let Cell = |q| {
    let m = ORD[q]
    let c = [-3.5 + 0.46 * (q - 8 * (q // 8)), 1.61 - 0.46 * (q // 8), 0]
    return [
        center{c} fill{SH[mono(m)]} stroke{PAPER, 2.5} Rect([0.46, 0.46]),
        map(range(0, 6), |i| Seg(corner(P4[i][0], c), corner(P4[i][1], c), EC[bit(m, i)], 2.2))
    ]
}
let Row = |y, c, word| [
    center{[0.85, y, 0]} fill{SH[c]} stroke{SLATE, 1.5} Rect([0.32, 0.32]),
    center{[2.3, y, 0]} Cap(str_join([word, to_string(nwith(c))]), 0.76, INK)
]
mesh cells = map(range(0, 64), |q| Cell(q))
mesh words = [
    center{[2.05, 1.65, 0]} Math("\text{the } 64 \text{ colorings of } K_4", 0.8, INK),
    Row(1.0, 0, "no triangle: "),
    Row(0.5, 1, "one triangle: "),
    Row(0.0, 2, "two triangles: "),
    Row(-0.5, 4, "four triangles: "),
    center{[2.05, -1.2, 0]} Math("\text{adding: } 4 \cdot \frac{16}{64} = 1", 0.78, SLATE),
    center{[2.05, -1.8, 0]} Math(str_join(["\text{truth: } \frac{", to_string(64 - nwith(0)), "}{64} \approx ", to_string((64 - nwith(0)) / 64, 2)]), 0.78, ROSE)
]

Uses the shared definitions for this lesson's figures.

The exact probability is $\frac{46}{64} \approx 0.72$. Computing it took a full enumeration, which is out of the question for large graphs. Adding the individual probabilities is cheap, and the picture shows that it can only overshoot.

Equality holds exactly when no outcome of positive probability lies in two of the events. For $K_4$ the bound gives $1$, which is true and useless. The bound is useful when the sum comes out below 1.

Pause and try

For which $n$ does the same calculation show that $K_n$ has a 2-coloring with no monochromatic clique of size 4? You need $\binom{n}{4} \cdot \frac{1}{32} < 1$.

Show answerHide answer

We need $\binom{n}{4} < 32$. Since $\binom{6}{4} = 15$ and $\binom{7}{4} = 35$, the calculation works up to $n = 6$ and says nothing from $n = 7$ on.

The union bound on the chance of a monochromatic clique of size 4 in a random coloring of the complete graph on n vertices, for n from 4 to 9. It is below 1 up to n = 6, which proves that a coloring with no such clique exists there, and above 1 from n = 7, where it proves nothing.
The union bound on the chance of a monochromatic clique of size 4 in a random coloring of the complete graph on n vertices, for n from 4 to 9. It is below 1 up to n = 6, which proves that a coloring with no such clique exists there, and above 1 from n = 7, where it proves nothing.
Monocurl source
let fb = Frame(3.4, 9.6, 0, 4.5, [0, -0.15, 0], 6.2, 3.0)
let val = |n| choose(n, 4) * 2 / 2 ^ 6
let barcol = |n| [ROSE, LEAF][val(n) < 1]
mesh grid = GridLines(fb, [], [1, 2, 3, 4])
mesh bars = map(range(4, 10), |n| [
    Shape([at(fb, n - 0.32, 0), at(fb, n + 0.32, 0), at(fb, n + 0.32, val(n)), at(fb, n - 0.32, val(n))], barcol(n), 0.4, 2.5),
    center{[fx(fb, n), fy(fb, val(n)) + 0.22, 0]} Math(to_string(val(n), 2), 0.74, barcol(n))
])
mesh one = stroke{INK, 2.5} dashed{} Line(at(fb, 3.4, 1), at(fb, 9.6, 1))
mesh axes = [
    Seg(at(fb, 3.4, 0), at(fb, 9.6, 0), SLATE, 2.5),
    Seg(at(fb, 3.4, 0), at(fb, 3.4, 4.5), SLATE, 2.5),
    XTicks(fb, range(4, 10)),
    YTicks(fb, [1, 2, 3, 4]),
    center{[fx(fb, 9.6) + 0.35, fy(fb, 0) - 0.33, 0]} Math("n", 0.85, SLATE)
]
mesh words = [
    center{[fx(fb, 3.4) + 1.35, 1.7, 0]} Math("\text{union bound } \binom{n}{4} \cdot 2^{-5}", 0.8, SLATE),
    center{[-1.2, fy(fb, 3.5), 0]} Cap("below 1: a good coloring exists", 0.74, LEAF),
    center{[-1.2, fy(fb, 2.5), 0]} Cap("above 1: no conclusion", 0.74, ROSE)
]

Uses the shared definitions for this lesson's figures.

Since $R(4,4) = 18$, the result $R(4,4) > 6$ is weak. The strength of the method is in how it grows with $k$.

The lower bound

Fix $k$ and color $K_n$ at random. There are $\binom{n}{k}$ sets of $k$ vertices, and each is monochromatic with probability $2 \cdot 2^{-\binom{k}{2}}$, where the factor of 2 accounts for the two possible colors. The union bound gives

$$ P(\text{some monochromatic clique of size } k) \le \binom{n}{k} \, 2^{1 - \binom{k}{2}}. $$

If we choose $n$ so that the right side is less than 1, then some coloring of $K_n$ has no monochromatic clique of size $k$, and therefore $R(k,k) > n$. What remains is to find out how large $n$ can be.

You might object that probability did no real work, and for this proof you would be right. Multiply everything by the number of colorings, and the argument says that the colorings with a monochromatic clique of size $k$, even counted with repetition, number fewer than the total, so some coloring is left over. The probabilistic language is bookkeeping for that count, and it stays manageable in later arguments where the coins are unfair.

Hay in a haystack

The proof says more than that a good coloring exists. For $k = 20$ we have $n = 2^{10} = 1024$, and the failure probability is below $\frac{2^{11}}{20!} \approx 8 \times 10^{-16}$. Almost every coloring of $K_{1024}$ has no monochromatic clique of size 20. Yet the proof hands us none of them, and to verify a candidate one would have to examine $\binom{1024}{20}$ sets of vertices, which is more than $10^{41}$. As far as I know, nobody has found an explicit, efficiently computable rule for coloring $K_n$ that provably avoids monochromatic cliques of size $k$ with $n$ growing like $c^k$ for some constant $c > 1$; finding one is a well-known open problem. A completely random method with no intelligence at all gives a better lower bound than the thought-out constructions. It’s as if we are unable to find hay in a haystack.

The result is an existence statement with no construction behind it. And the two bounds in the key statement are far apart: one grows like $1.414^k$ and the other like $4^k$. The base $\sqrt2$ of the lower bound has not been improved since 1947. In 2023 Campos, Griffiths, Morris and Sahasrabudhe announced the first improvement in the base of the upper bound, to $(4 - \varepsilon)^k$ for a small constant $\varepsilon > 0$.

The probabilistic method has since become a standard technique in combinatorics for proving the existence of objects that no one knows how to construct explicitly. The reusable step is to replace “find one” by “show that a random one works with positive probability”.

To illustrate how challenging the problem remains despite its simple statement, Joel Spencer recounts the following anecdote: “Erdős asks us to imagine an alien force, vastly more powerful than us, landing on Earth and demanding the value of $R(5, 5)$ or they will destroy our planet. In that case, he claims, we should marshal all our computers and all our mathematicians and attempt to find the value. But suppose, instead, that they ask for $R(6, 6)$. In that case, he believes, we should attempt to destroy the aliens.” For $R(6,6)$ the known bounds are far apart: it is at least 102, and the best proved upper bound is 160.

Check yourself

A random 2-coloring of $K_5$ has 10 triangles, each monochromatic with probability $\frac14$, so the union bound on “some triangle is monochromatic” is $2.5$. What follows?

Problems

Problems 1 and 2 repeat the lesson’s moves, 3 to 5 combine them, and 6 and 7 go further.

Problem 1

Use the theorem of Erdős and Szekeres to show that $R(3,4) \le 10$ and $R(4,4) \le 20$. Check both against the binomial bound.

Show solutionHide solution

By the recurrence and the base case $R(2,4) = 4$, we get $R(3,4) \le R(2,4) + R(3,3) = 4 + 6 = 10$. Exchanging the two colors in the definition shows $R(4,3) = R(3,4)$, so $R(4,4) \le R(3,4) + R(4,3) \le 10 + 10 = 20$. The binomial bound gives $\binom{3+4-2}{2} = \binom{5}{2} = 10$ and $\binom{6}{3} = 20$, the same numbers. (The true values are $R(3,4) = 9$ and $R(4,4) = 18$.)

Problem 2

Each edge of $K_n$ is colored blue or orange by a fair coin flip. (a) Find the expected number of monochromatic triangles, and evaluate it for $n = 6$. (b) For $n = 5$ the expected number is $2.5$, yet the pentagon coloring has none. Why is there no contradiction?

Show solutionHide solution

(a) For each of the $\binom{n}{3}$ triangles $T$, let $X_T$ be 1 if $T$ is monochromatic and 0 otherwise. Its expected value is $P(T \text{ is monochromatic}) = 2 \cdot 2^{-3} = \frac14$. The number of monochromatic triangles is the sum of the $X_T$, and the expected value of a sum is the sum of the expected values, whether or not the terms are independent. So the expected number is $\frac14\binom{n}{3}$. For $n = 6$ it is $\frac{20}{4} = 5$. (b) An expected value is an average over all colorings. An average of 2.5 requires some colorings with at most 2 monochromatic triangles and some with at least 3, and puts no other restriction on the smallest value, which can be 0. The number 2.5 is also the union bound: the sum of the probabilities of the events is the expected number of events that occur.

Problem 3

Now use three colors. Show that the edges of $K_{10}$ can be colored red, green and blue so that no four vertices have all six of their edges the same color.

Show solutionHide solution

Color each edge independently, with each color having probability $\frac13$. All $3^{45}$ colorings are equally likely. A given set of four vertices has 6 edges, and they all agree in 3 of the $3^6$ ways to color them, so the set is monochromatic with probability $3 \cdot 3^{-6} = \frac{1}{243}$. There are $\binom{10}{4} = 210$ such sets. By the union bound the probability that some set of four is monochromatic is at most $\frac{210}{243} < 1$. So with positive probability no set is, and a coloring of the required kind exists. For $K_{11}$ the same sum is $\frac{330}{243} > 1$ and this argument gives nothing.

Problem 4

Split $(k-1)^2$ vertices into $k - 1$ groups of $k - 1$ vertices each. Color an edge blue if its ends are in the same group and orange otherwise. Show that this proves $R(k,k) > (k-1)^2$, and compare with $2^{k/2}$ for $k = 20$ and $k = 40$.

Show solutionHide solution

In a blue clique every two vertices are in the same group, so the whole clique lies in one group and has at most $k - 1$ vertices. In an orange clique every two vertices are in different groups, so it has at most one vertex per group, again at most $k - 1$. So this coloring of $K_{(k-1)^2}$ has no monochromatic clique of size $k$, and $R(k,k) > (k-1)^2$. For $k = 20$ that is $361$ against $2^{10} = 1024$. For $k = 40$ it is $1521$ against $2^{20} = 1{,}048{,}576$. The construction grows like $k^2$ and the random bound grows exponentially.

Problem 5

For triangles in $K_5$ the union bound is $2.5$. Find the exact probability that a random 2-coloring of $K_5$ has a monochromatic triangle, by showing that exactly 12 of the $2^{10} = 1024$ colorings are valid.

Show solutionHide solution

Take a valid coloring. If some vertex $v$ had three edges of one color, to $x$, $y$ and $z$, the argument for $K_6$ would apply word for word: an edge among $x, y, z$ of that color closes a triangle with $v$, and otherwise $x, y, z$ is a triangle of the other color. So every vertex has at most two edges of each color, and since it has four edges, exactly two blue and two orange. Now follow the blue edges. Each vertex lies on exactly two of them, so the blue edges form closed loops with no vertex shared between loops. A loop has at least 3 vertices and there are 5 vertices, so there is a single loop through all five. Conversely, if the blue edges form a loop through all five vertices, draw the vertices around a pentagon in the order of the loop. This is the pentagon coloring with the colors exchanged, and it is valid by the gap argument. So the valid colorings correspond to the loops through five labeled vertices. There are $5! = 120$ ways to list the vertices in order, and each loop is listed $10$ times (5 starting points, 2 directions), which makes $12$ loops. The probability of a monochromatic triangle is $\frac{1024 - 12}{1024} = \frac{1012}{1024} \approx 0.988$. The union bound of 2.5 is correct and far from tight, because a typical coloring has several monochromatic triangles and the sum counts it once for each.

Problem 6

Every edge of $K_{17}$ is colored red, green or blue. Prove that there is a monochromatic triangle.

Show solutionHide solution

Fix a vertex $v$. It has 16 edges in 3 colors, so by the pigeonhole principle at least $\lceil 16/3 \rceil = 6$ of them share a color, say red, and they lead to six vertices $x_1, \dots, x_6$. If some edge $x_i x_j$ is red, then $v, x_i, x_j$ is a red triangle. Otherwise every edge among the six vertices is green or blue, which is a 2-coloring of $K_6$, and by the theorem that $R(3,3) \le 6$ it contains a green or a blue triangle. (Greenwood and Gleason showed in 1955 that 17 cannot be lowered.)

Problem 7

Show that every 2-coloring of $K_6$ contains at least two monochromatic triangles.

Show solutionHide solution

Call two edges that meet at a vertex a mixed corner if they have different colors. A triangle that is not monochromatic has two edges of one color and one of the other, so exactly two of its three corners are mixed: the two at the ends of the odd edge. A monochromatic triangle has no mixed corner. Now count mixed corners vertex by vertex. A vertex with $b$ blue edges and $5 - b$ orange edges is the meeting point of $b(5 - b)$ mixed corners, and $b(5-b)$ takes the values $0, 4, 6, 6, 4, 0$ for $b = 0, \dots, 5$, so it is at most 6. Over the six vertices there are at most 36 mixed corners. Every triangle that is not monochromatic uses up two of them, so at most 18 triangles are not monochromatic. $K_6$ has $\binom{6}{3} = 20$ triangles, so at least 2 are monochromatic.

Shared definitions used by this lesson's figures
# house kit: prepended to every essay figure after the std imports

# palette. AZURE and EMBER are the two actors, LEAF marks an answer, ROSE a problem
let PAPER = [1, 1, 1, 1]
let INK = [0.08, 0.09, 0.11, 1]
let SLATE = [0.40, 0.44, 0.50, 1]
let MIST = [0.85, 0.86, 0.88, 1]
let AZURE = [0.13, 0.42, 0.68, 1]
let EMBER = [0.89, 0.42, 0.12, 1]
let LEAF = [0.13, 0.55, 0.36, 1]
let ROSE = [0.78, 0.22, 0.24, 1]
let PLUM = [0.47, 0.30, 0.66, 1]
let GOLD = [0.85, 0.62, 0.08, 1]

background = PAPER

# an opaque pastel of col; use for fills so overlaps do not darken
let tint = |col, amount = 0.18| [
    1 - (1 - col[0]) * amount,
    1 - (1 - col[1]) * amount,
    1 - (1 - col[2]) * amount,
    1
]

# text: Cap for labels, Note for quiet labels, Math for typeset maths
let Cap = |txt, size = 0.75, col = INK| color{col} Text(txt, size, "Charter")
let Note = |txt, size = 0.65| color{SLATE} Text(txt, size, "Charter")
let Math = |tex, size = 0.9, col = INK| color{col} Tex(tex, size)

# a paper rectangle to sit behind text that crosses lines
let Plate = |pos, size| center{pos} fill{PAPER} stroke{alpha{0} PAPER, 0} Rect(size)

# shapes with fill and stroke both set, so no stray black appears
let Pt = |pos, col = INK, r = 0.075| center{pos} fill{col} stroke{col, 1} Circle(r, 48)
let Ring = |pos, col = INK, r = 0.1, w = 3| center{pos} fill{PAPER} stroke{col, w} Circle(r, 48)
let Seg = |a, b, col = INK, w = 3| stroke{col, w} Line(a, b)
let Path = |pts, col = INK, w = 3| stroke{col, w} Polyline(pts)
let Region = |pts, col| fill{col} stroke{alpha{0} col, 0} Polygon(pts)
let Outline = |pts, col = INK, w = 3| fill{alpha{0} PAPER} stroke{col, w} Polygon(pts)
let Shape = |pts, col, amount = 0.18, w = 3| fill{tint(col, amount)} stroke{col, w} Polygon(pts)
let Disc = |pos, r, col, amount = 0.18, w = 3| center{pos} fill{tint(col, amount)} stroke{col, w} Circle(r, 96)
let Box = |pos, size, col, amount = 0.18, w = 3| center{pos} fill{tint(col, amount)} stroke{col, w} Rect(size)
# a line from a to b ending in a small solid arrowhead
let Tip = |a, b, col = INK, w = 3, head = 0.17| {
    let d = normalize([b[0] - a[0], b[1] - a[1], 0])
    let n = [-d[1], d[0], 0]
    let base = [b[0] - d[0] * head, b[1] - d[1] * head, 0]
    return [
        stroke{col, w} Line(a, base),
        fill{col} stroke{col, 1} Polygon([
            b,
            [base[0] + n[0] * head * 0.42, base[1] + n[1] * head * 0.42, 0],
            [base[0] - n[0] * head * 0.42, base[1] - n[1] * head * 0.42, 0]
        ])
    ]
}

# plots. a frame is [x0, x1, y0, y1, centre, width, height]: a data window and the scene box it fills
let Frame = |x0, x1, y0, y1, c = [0, 0, 0], w = 6.4, h = 3.6| [x0, x1, y0, y1, c, w, h]
let fx = |fr, x| fr[4][0] + (x - (fr[0] + fr[1]) / 2) * fr[5] / (fr[1] - fr[0])
let fy = |fr, y| fr[4][1] + (y - (fr[2] + fr[3]) / 2) * fr[6] / (fr[3] - fr[2])
let at = |fr, x, y| [fx(fr, x), fy(fr, y), 0]

# axes through the data origin (or the nearest edge of the window), with optional names
let Axes = |fr, x_name = "", y_name = "", col = SLATE| {
    let ox = clamp(fr[0], 0, fr[1])
    let oy = clamp(fr[2], 0, fr[3])
    var parts = [
        Tip(at(fr, fr[0], oy), [fx(fr, fr[1]) + 0.25, fy(fr, oy), 0], col, 2.5, 0.15),
        Tip(at(fr, ox, fr[2]), [fx(fr, ox), fy(fr, fr[3]) + 0.25, 0], col, 2.5, 0.15)
    ]
    if (x_name != "") {
        parts .= center{[fx(fr, fr[1]) + 0.5, fy(fr, oy), 0]} Math(x_name, 0.8, col)
    }
    if (y_name != "") {
        parts .= center{[fx(fr, ox), fy(fr, fr[3]) + 0.5, 0]} Math(y_name, 0.8, col)
    }
    return parts
}

# tick marks with numbers at the listed data values
let XTicks = |fr, xs, col = SLATE, places = 0| block {
    let oy = fy(fr, clamp(fr[2], 0, fr[3]))
    for (x in xs) {
        . Seg([fx(fr, x), oy - 0.07, 0], [fx(fr, x), oy + 0.07, 0], col, 2)
        . center{[fx(fr, x), oy - 0.33, 0]} Math(to_string(x, places), 0.72, col)
    }
}
let YTicks = |fr, ys, col = SLATE, places = 0| block {
    let ox = fx(fr, clamp(fr[0], 0, fr[1]))
    for (y in ys) {
        . Seg([ox - 0.07, fy(fr, y), 0], [ox + 0.07, fy(fr, y), 0], col, 2)
        . center{[ox - 0.36, fy(fr, y), 0]} Math(to_string(y, places), 0.72, col)
    }
}

# faint grid lines at the listed data values
let GridLines = |fr, xs, ys, col = MIST| block {
    for (x in xs) {
        . Seg(at(fr, x, fr[2]), at(fr, x, fr[3]), col, 1.5)
    }
    for (y in ys) {
        . Seg(at(fr, fr[0], y), at(fr, fr[1], y), col, 1.5)
    }
}

# the graph of f over [a, b], drawn in the frame. values are clamped to the window
let Graph = |fr, f, a, b, col = AZURE, w = 4, n = 160|
    stroke{col, w} Polyline(map(sample(a, b, n), |x| at(fr, x, clamp(fr[2], f(x), fr[3]))))

# the region between the graph of f and the x axis over [a, b]
let AreaUnder = |fr, f, a, b, col = AZURE, amount = 0.2, n = 80| {
    var pts = [at(fr, a, 0)]
    for (x in sample(a, b, n)) {
        pts .= at(fr, x, clamp(fr[2], f(x), fr[3]))
    }
    pts .= at(fr, b, 0)
    return fill{tint(col, amount)} stroke{alpha{0} col, 0} Polygon(pts)
}

# double hash generator: a value in [0, 1) for each (i, salt)
let frac = |x| x - floor(x)
let rnd = |i, salt| frac(sin(i * 39.3468 + salt * 11.135 + frac(sin(i * 12.9898 + salt * 78.233) * 43758.5453) * 6.2831853) * 24634.6345)
let NAMES = ["A", "B", "C", "D", "E", "F"]
# edge colors: index 1 is blue (friends), index 0 is orange (strangers)
let EC = [EMBER, AZURE]
let ring = |n, i, c, r| [c[0] + r * sin(TAU * i / n), c[1] + r * cos(TAU * i / n), 0]
let pairs = |n| block {
    for (i in range(0, n)) {
        for (j in range(i + 1, n)) {
            . [i, j]
        }
    }
}
let rest = |n, az| filter(pairs(n), |e| not (e in az))
# the blue edges of a coin-flip coloring of K6
let raz = |g| filter(pairs(6), |e| rnd(e[0] * 7 + e[1] + 1, g) < 0.5)
# the first one-color triangle of a coloring with blue edges az, or [] if there is none
let find_tri = |n, az| {
    var f = []
    for (i in range(0, n)) {
        for (j in range(i + 1, n)) {
            for (k in range(j + 1, n)) {
                let s = ([i, j] in az) + ([j, k] in az) + ([i, k] in az)
                if (len(f) == 0 and (s == 0 or s == 3)) {
                    f = [i, j, k]
                }
            }
        }
    }
    return f
}
# edges of K_n on a ring: blue if in az, orange if in em, gray otherwise. hi is a triangle to expose
let Edges = |n, c, r, az, em, hi = [], w = 4| {
    let on = |e| len(hi) == 0 or (e[0] in hi and e[1] in hi)
    let col = |e| [[MIST, EMBER][e in em], AZURE][e in az]
    var parts = []
    if (len(hi) == 3) {
        parts .= Region(map(hi, |v| ring(n, v, c, r)), tint(ROSE, 0.22))
    }
    for (e in pairs(n)) {
        if (not on(e)) {
            parts .= Seg(ring(n, e[0], c, r), ring(n, e[1], c, r), tint(col(e), 0.3), w)
        }
    }
    for (e in pairs(n)) {
        if (on(e)) {
            parts .= Seg(ring(n, e[0], c, r), ring(n, e[1], c, r), col(e), [w, w + 2][len(hi) == 3])
        }
    }
    return parts
}
let Guests = |n, c, r, hi = [], rad = 0.27, size = 0.8| map(range(0, n), |v| [
    Disc(ring(n, v, c, r), rad, [SLATE, ROSE][v in hi], 0.2, 2.5),
    center{ring(n, v, c, r)} Cap(NAMES[v], size, [INK, ROSE][v in hi])
])