A Short Path to Enumerative Graph Theory · Front matter and Chapters 1–4, draft of 4 October 2026
Contents
Beauty is the first test: there is no permanent place in the world for ugly mathematics.
— G. H. Hardy, A Mathematician’s Apology, 1940
How many ways are there to connect ten cities by roads so that no road is wasted? How many different molecules can be built from six carbon atoms? How many friendship networks on twenty people contain no three mutual friends, and what is the largest number of friendships such a network can have? Each of these is a question about graphs, and each asks for a number. This book is about such questions and about the many different things that can count as their answers.
Arthur Cayley (1821–1895)
English mathematician and, for fourteen years, a lawyer. His counts of trees and of chemical isomers in the 1850s–1870s are the first chapter of enumerative graph theory.
As for everything else, so for a mathematical theory: beauty can be perceived but not explained.
— attributed
Graph theory began with a counting flavour. Euler’s solution of the Königsberg bridges problem in 1736 is a parity argument, which is counting modulo \(2\). Cayley’s work on trees in the nineteenth century was motivated by counting molecules. Pólya’s theorem of 1937 turned the counting of objects up to symmetry into an algebraic machine. Since then the subject has grown in two directions at once: towards deep exact formulas, and towards estimates and bounds for numbers that have no formula at all.
The classical reference on counting graphs, Harary and Palmer’s Graphical Enumeration, appeared in 1973 and concentrates on Pólya’s method. Many of the ideas that a student meets today, such as the Matrix-Tree Theorem in its modern forms, the exponential formula, random graphs and the probabilistic method, and the extremal theorems of Turán and Ramsey, are scattered among books on combinatorics, algebraic graph theory and probability. We wanted one book in which they meet, and in which the reader can watch the same question receive different kinds of answers.
Herbert S. Wilf (1931–2012)
American combinatorialist at the University of Pennsylvania, author of generatingfunctionology (1990). His short paper What is an answer? (1982) shaped the plan of this book.
Herbert Wilf once asked what it means to answer a counting question. A closed formula such as \(n^{n-2}\) is the answer everyone hopes for, but it is rare. A recurrence may be just as useful if it lets us compute the numbers quickly. A generating function packs an infinite sequence into one equation. An asymptotic formula tells us how fast the numbers grow when no exact formula is known. And sometimes the right question is not “how many?” but “how many at most?”, and the answer is an inequality that cannot be improved.
This observation decides the order of our chapters. Chapter 1 sets up the language. Chapters 2 and 3 look for explicit formulas, first with elementary tools and then with linear algebra and group actions. Chapter 4 looks for recurrences, Chapter 5 for generating functions, Chapter 6 for estimates, and Chapter 7 for extremal values. Two problems, the counting of trees and the counting of connected graphs, travel through every chapter, so that the reader can see one question answered in five ways.
The book is written for undergraduate and graduate students of mathematics and computer science, for students preparing for mathematical and informatics olympiads, and for young researchers who want to find a problem of their own. We assume only what a first course in discrete mathematics provides: sets, functions, induction and a little linear algebra. Everything else, including the facts about groups, probability and power series that we use, is explained when it is needed or collected in the appendices.
This book is published as an e-book in two editions built from one source. The web edition, at mbooks.arith.land, is interactive: every key term shows its definition when you point at it, every program can be run, many sections contain small laboratories in which you can change a number and watch the answer change, and some theorems come with a short recorded comment by one of the authors. The PDF edition is laid out for a tablet held sideways, with history and quotations in a wide margin, as in our earlier e-books. Both editions contain the same mathematics.
Every chapter ends with exercises of several kinds, marked by tags: purely mathematical exercises, problems from mathematical and informatics olympiads, algorithmic and programming tasks, and research projects divided into small steps. Many exercises have hints that can be opened one at a time and an answer that can be checked without being revealed. The Research threads scattered through the text describe open problems, with their status at the time of writing and a concrete first step. We hope that some readers will take one of these steps and keep walking.
Some sections describe results from our own papers. Those that have not yet been accepted for publication are cited as preprints, and the citations will be updated as the refereeing process ends.
[To be written by the authors.]
Our books change with the comments of their readers, and every later version owes much to the readers of the earlier one. We look forward to your corrections and suggestions, always.
Madjid Mirzavaziri, Ferdowsi University of Mashhad Daniel Yaqubi, University of Torbat-e Jam 2026
The only way to learn mathematics is to do mathematics.
— Paul Halmos, A Hilbert Space Problem Book, 1967
This short section explains how the book is organised and how its parts are marked. A reader who prefers to start at once can go straight to Chapter 1 and come back here when a symbol or a box needs explaining.
| Chapter | Kind of answer | Typical result |
|---|---|---|
| 1 Prerequisites | the language and the tools | the handshake lemma, \(n!/|\mathrm{Aut}(G)|\) labelings |
| 2 Elementary explicit answers | a closed formula by elementary means | \(2^{\binom n2}\) graphs, \(n^{n-2}\) trees |
| 3 Advanced explicit answers | a formula from linear algebra or symmetry | the Matrix-Tree Theorem, Pólya’s theorem |
| 4 Recursive answers | a recurrence | deletion–contraction, transfer matrices |
| 5 Generating-function answers | a power series | the exponential formula, Lagrange inversion |
| 6 Approximate answers | an estimate | almost all graphs are connected |
| 7 Extremal problems | a sharp bound | Turán, Ramsey, Hall, Dilworth |
Definitions, theorems, lemmas, propositions, corollaries, examples and remarks share one counter in each section, as in our earlier books: Definition 1.2.1 may be followed by Theorem 1.2.2 and Example 1.2.3. This makes every numbered block easy to find. Definitions end with the mark \(\clubsuit\), examples with \(\spadesuit\), remarks with \(\diamondsuit\), and proofs with \(\blacksquare\).
The margin holds three kinds of notes, always next to the paragraph they belong to: a short portrait of a mathematician when his or her name first appears, a historical note, and a quotation. Nothing in the margin is needed to follow the mathematics, but we hope it shows that every theorem was found by a person, at a time, for a reason.
Each exercise carries one or more tags:
| Tag | Meaning |
|---|---|
| Pure | a mathematical exercise with a proof as its answer |
| Math Olympiad | a problem in the style of mathematical olympiads, often from one |
| Informatics Olympiad | a problem in the style of programming contests |
| Algorithm | design an algorithm and analyse its running time |
| Code | write and run a program |
| Computer Science | a question about computation, complexity or data structures |
| Research Project | a sequence of small steps that leads to an open question |
Hints are numbered and, in the web edition, open one at a time; try the problem again after each hint. When an exercise has a numerical answer, the web edition lets you check your number without seeing the answer. The PDF edition collects hints and answers at the end of each chapter.
Programs are written in plain Python 3 so that they run anywhere: in the web edition, in SageMathCell, or on your own computer. We prefer short, transparent programs to fast ones; the exercises tagged Algorithm ask you to make them fast. Appendix C collects every program in the book.
The symbols below are used throughout the book. Each is defined again where it first appears; this page is for quick reference.
| Symbol | Meaning |
|---|---|
| \([n]\) | the set \(\{1,2,\ldots,n\}\); \([0]=\varnothing\) |
| \(\binom nk\) | binomial coefficient, the number of \(k\)-subsets of \([n]\) |
| \(\binom{n}{k_1,\ldots,k_r}\) | multinomial coefficient \(n!/(k_1!\cdots k_r!)\) |
| \(n^{\underline k}\) | falling factorial \(n(n-1)\cdots(n-k+1)\) |
| \(S(n,k)\) | Stirling number of the second kind |
| \(c(n,k)\) | unsigned Stirling number of the first kind |
| \(B_n\), \(\mathrm{Cat}_n\), \(F_n\), \(D_n\), \(p(n)\) | Bell, Catalan, Fibonacci, derangement and partition numbers |
| \(G=(V,E)\) | a graph with vertex set \(V\) and edge set \(E\) |
| \(D=(V,\vec E)\) | a directed graph |
| \(n=\lvert V\rvert\), \(m=\lvert E\rvert\) | order and size of a graph |
| \(uv\) | the edge \(\{u,v\}\), or the arc from \(u\) to \(v\) in a digraph |
| \(N(v)\), \(N[v]\) | open and closed neighbourhood |
| \(\deg(v)\); \(d^+(v)\), \(d^-(v)\) | degree; out-degree and in-degree |
| \(\delta(G)\), \(\Delta(G)\) | minimum and maximum degree |
| \(d(u,v)\) | distance |
| \(\mathrm{ecc}(v)\), \(\mathrm{rad}(G)\), \(\mathrm{diam}(G)\) | eccentricity, radius, diameter |
| \(\kappa(G)\) | number of connected components |
| \(G[U]\) | subgraph induced by a vertex set \(U\) |
| \(\overline G\) | complement |
| \(G\cong H\) | \(G\) and \(H\) are isomorphic |
| \(\mathrm{Aut}(G)\) | automorphism group |
| \(K_n\), \(K_{n_1,\ldots,n_r}\), \(P_n\), \(C_n\), \(W_n\), \(Q_n\) | complete, complete multipartite, path, cycle, wheel and hypercube graphs |
| \(\tau(G)\) | number of spanning trees |
| \(P(G,k)\) | chromatic polynomial |
| \(t_n\) | number of labeled trees on \([n]\) |
| \(\mathcal C_n\) | number of connected labeled graphs on \([n]\) |
A path \(P_n\) has \(n\) vertices and \(n-1\) edges, and a cycle \(C_n\) has \(n\) vertices and \(n\) edges. (The 2014 Persian edition wrote \(P_{n+1}\) for the path of length \(n\); we now index paths by their order, as most recent books do.) Logarithms without a base are natural logarithms.
Many problems in mathematics are easier to think about once we draw a picture. In geometry the picture keeps lengths and angles; in a Venn diagram it keeps only which sets contain which elements. There are problems where neither is enough, because what matters is a relation between objects: which people in a group are friends, which cities are joined by a direct flight, which atoms in a molecule are bonded, which web pages link to which. For such problems we draw a dot for each object and a line between two dots whenever the two objects are related. How long the line is, whether it is straight or curved, and where the dots are placed do not matter at all.
This simple idea is the idea of a graph. In this section we turn it into a definition precise enough to count with.
Definition 1.1.1. A graph \(G=(V,E)\) consists of a set \(V\), whose elements are called vertices, and a multiset \(E\) of subsets of \(V\) with one or two elements, called edges. The number of vertices \(|V|\) is the order of \(G\) and the number of edges \(|E|\) is its size. An edge \(e=\{u,v\}\) is written \(uv\); the vertices \(u\) and \(v\) are its ends.
Because \(E\) is a multiset, two vertices may be joined by several edges, called parallel edges; and because an edge may have one element, a vertex may be joined to itself by a loop. A graph without loops and parallel edges is called simple. Throughout this book graphs are finite and simple unless we say otherwise. Vertices are also called nodes and edges lines.
Remark 1.1.2. A drawing of a graph places a point for each vertex and joins the points of \(u\) and \(v\) by a curve whenever \(uv\) is an edge. One graph has infinitely many drawings, and two drawings that look very different may show the same graph. The drawing is a tool for thinking; the graph is the pair \((V,E)\).
Leonhard Euler (1707–1783)
Swiss mathematician who worked in St Petersburg and Berlin. His 1736 paper on the bridges of Königsberg is regarded as the first paper of graph theory.
The first graph problem on record is the problem of the seven bridges of Königsberg, solved by Euler in 1736. The four land masses of the town become four vertices and the seven bridges become seven edges, two pairs of them parallel. Euler asked whether one can walk across every bridge exactly once. We will answer the question in Section 2.8; for the moment notice that it already needs multigraphs.
Laplace is reported to have told his students: “Read Euler, read Euler, he is the master of us all.” Euler wrote about 850 papers and books; his collected works are still being published.
Some relations have a direction: \(a\) is a parent of \(b\), \(a\) beat \(b\) in a match, page \(a\) links to page \(b\). For these we use arrows instead of lines.
Definition 1.1.3. A directed graph or digraph \(D=(V,\vec E)\) consists of a set \(V\) of vertices and a multiset \(\vec E\) of ordered pairs of vertices, called arcs. For an arc \((u,v)\), written \(uv\), the vertex \(u\) is its tail and \(v\) its head. Forgetting the directions of all arcs gives the underlying graph of \(D\).
Definition 1.1.4. Let \(G=(V,E)\) be a graph. Two vertices are adjacent, or neighbours, if they are joined by an edge. The open neighbourhood \(N(v)\) of a vertex \(v\) is the set of its neighbours, and the closed neighbourhood is \(N[v]=N(v)\cup\{v\}\). The degree \(\deg(v)\) of \(v\) is the number of edges at \(v\); in a simple graph \(\deg(v)=|N(v)|\). A vertex is even or odd according to the parity of its degree, and isolated if its degree is \(0\). We write \(\delta(G)\) and \(\Delta(G)\) for the minimum and maximum degree, and call \(G\) \(k\)-regular if every vertex has degree \(k\).
In a digraph, the out-degree \(d^+(v)\) is the number of arcs with tail \(v\) and the in-degree \(d^-(v)\) the number of arcs with head \(v\).
Our first theorem is the oldest counting argument in graph theory. It counts one set in two ways, a technique called double counting that we will use again and again.
Theorem 1.1.5 (Handshake lemma). For every graph \(G=(V,E)\), \[\sum_{v\in V}\deg(v)=2|E|.\] For every digraph \(D=(V,\vec E)\), \[\sum_{v\in V}d^+(v)=\sum_{v\in V}d^-(v)=|\vec E|.\]
Proof of Theorem 1.1.5. Count the pairs \((v,e)\) in which \(v\) is an end of the edge \(e\), a loop being counted twice at its vertex. Grouping the pairs by \(v\) gives \(\sum_v\deg(v)\); grouping them by \(e\) gives \(2\) for every edge. In a digraph, count pairs \((v,e)\) in which \(v\) is the tail of \(e\): grouping by \(v\) gives \(\sum_v d^+(v)\) and grouping by \(e\) gives \(|\vec E|\). Heads are treated in the same way.
Corollary 1.1.6. In every graph the number of odd vertices is even.
Proof. The sum of all degrees is even by Theorem 1.1.5. The even degrees contribute an even amount, so the sum of the odd degrees is even too, which is possible only if there is an even number of them.
Example 1.1.7. At a party of five people, can everybody shake hands with exactly three others? Such a party would be a \(3\)-regular graph on \(5\) vertices, with degree sum \(15\). Since \(15\) is odd, Theorem 1.1.5 says this is impossible.
James Joseph Sylvester (1814–1897)
English mathematician who taught in London, Baltimore and Oxford. In a note in Nature in 1878 he used the word graph for the diagrams of chemical bonds, and the name stayed.
May not music be described as the mathematics of the sense, mathematics as music of the reason?
— Philosophical Transactions of the Royal Society, 1864
How many simple graphs are there on the vertex set \([n]=\{1,2,\ldots,n\}\)? A simple graph is decided by choosing, for each of the \(\binom n2\) pairs of vertices, whether the pair is an edge. These choices are independent, so the product rule gives the answer.
Proposition 1.1.8. The number of simple graphs on \([n]\) is \(2^{\binom n2}\), and the number of those with exactly \(m\) edges is \(\binom{\binom n2}{m}\).
For \(n=1,2,\ldots,6\) the first number is \(1, 2, 8, 64, 1024, 32768\). These graphs are different as pairs \((V,E)\), but many of them have the same drawing up to renaming the vertices: of the \(8\) graphs on \([3]\), three are a single edge and three are a path. Section 1.3 makes this distinction precise; it is the most important distinction in the book.
from itertools import combinations
from collections import Counter
def all_graphs(n):
"""Every simple graph on 1..n, as a list of edges."""
pairs = list(combinations(range(1, n + 1), 2))
for mask in range(1 << len(pairs)):
yield [pairs[i] for i in range(len(pairs)) if mask >> i & 1]
def degrees(n, edges):
d = {v: 0 for v in range(1, n + 1)}
for u, v in edges:
d[u] += 1; d[v] += 1
return d
for n in range(1, 6):
by_size = Counter()
for E in all_graphs(n):
assert sum(degrees(n, E).values()) == 2 * len(E) # the handshake lemma
by_size[len(E)] += 1
print(n, sum(by_size.values()), [by_size[m] for m in range(n * (n - 1) // 2 + 1)])
The program lists all graphs on \([n]\) for \(n\leqslant5\), checks the handshake lemma for each of them, and prints how many there are of each size. For \(n=4\) the row is \(1, 6, 15, 20, 15, 6, 1\), the binomial coefficients \(\binom 6m\), as Proposition 1.1.8 predicts.
Lab · Graph sketchpad
The reader adds vertices with a click and edges by dragging between two vertices. The lab shows the degree of every vertex, the degree sequence, the number of odd vertices, and checks the handshake lemma live. Buttons load the graphs of the gallery in Section 1.5.
This lab is being built for the web edition.
Exercise 1.1.1 Pure Math Olympiad
Prove that every simple graph with at least two vertices has two vertices of the same degree.
The possible degrees in a graph of order \(n\) are \(0,1,\ldots,n-1\).
Degrees \(0\) and \(n-1\) cannot both occur. Use the pigeonhole principle.
Exercise 1.1.2 Math Olympiad
A graph has \(15\) vertices, each of degree \(3\) or \(4\), and \(24\) edges. How many vertices have degree \(4\)?
Let \(x\) be the number of vertices of degree \(4\) and apply Theorem 1.1.5.
Exercise 1.1.3 Pure
How many digraphs without loops and without parallel arcs are there on \([n]\)? (Arcs \(uv\) and \(vu\) may both be present.)
Each of the \(n(n-1)\) ordered pairs is an arc or not.
Exercise 1.1.4 Pure
How many simple graphs on \([n]\) have exactly \(m\) edges and an isolated vertex \(1\)?
The edges are chosen among the pairs that avoid the vertex \(1\).
Exercise 1.1.5 Pure Math Olympiad
Prove that a sequence \(d_1\geqslant d_2\geqslant\cdots\geqslant d_n\) of non-negative integers is the degree sequence of some loopless multigraph if and only if \(\sum d_i\) is even and \(d_1\leqslant d_2+\cdots+d_n\).
Necessity: the handshake lemma, and the edges at the first vertex go to the others.
Sufficiency: induct on \(\sum d_i\), joining the vertex of largest degree to the vertex of second largest degree.
Exercise 1.1.6 Computer Science Algorithm
A graph with \(n\) vertices and \(m\) edges can be stored as an adjacency matrix or as adjacency lists. Compare the memory used and the time needed to (a) test whether \(uv\) is an edge, (b) list the neighbours of \(v\), (c) compute all degrees. For which graphs is each structure better?
Exercise 1.1.7 Code
Modify the program of this section so that it also counts, for each \(n\leqslant5\), the graphs on \([n]\) with no odd vertex. Compare your numbers with \(2^{\binom{n-1}2}\) and make a conjecture. (Section 2.1 proves it.)
Once we have a graph we want to move around in it: from a city to another city along roads, from a person to a stranger through a chain of friends. This section makes such movement precise and introduces the first measurements of a graph: distance, radius and diameter.
Definition 1.2.1. Let \(G\) be a graph or a digraph and \(u,v\) vertices. A \(uv\)-walk of length \(k\) is a sequence of vertices \(u=u_0,u_1,\ldots,u_k=v\) such that \(u_{i-1}u_i\) is an edge (an arc, in a digraph) for every \(i\). The walk is closed if \(u=v\). A walk with no repeated edge is a trail; a walk with no repeated vertex is a path. A closed trail is a circuit, and a closed walk of length \(k\geqslant3\) whose vertices \(u_0,\ldots,u_{k-1}\) are distinct is a cycle or \(k\)-gon. Cycles of length \(3\) and \(4\) are triangles and squares.
Every path is a trail, because a repeated edge would bring its ends twice. The converse fails: the trail \(1,2,3,4,2,5\) in a graph made of a triangle \(234\) with two pendant edges \(12\) and \(25\) visits \(2\) twice.
Lemma 1.2.2. Every \(uv\)-walk contains a \(uv\)-path; that is, the vertices of some \(uv\)-path appear, in order, among the vertices of the walk.
Proof. Among all \(uv\)-walks whose vertices are taken, in order, from the given walk, choose one of minimum length. If a vertex appeared twice in it, cutting out the part between its two appearances would give a shorter such walk. So no vertex repeats, and the walk is a path.
Definition 1.2.3. The girth of a graph is the length of its shortest cycle and its circumference is the length of its longest cycle; both are \(\infty\) for a graph without cycles. The distance \(d(u,v)\) is the length of a shortest \(uv\)-walk, or \(\infty\) if there is none. By Lemma 1.2.2 a shortest walk is a path.
Definition 1.2.4. A graph is connected if there is a walk between every two of its vertices. A digraph is strongly connected if for every two vertices \(u,v\) there is a directed walk from \(u\) to \(v\), and weakly connected if its underlying graph is connected. A connected component is a maximal connected subgraph. We write \(\kappa(G)\) for the number of components.
Theorem 1.2.5. The relation “there is a walk from \(u\) to \(v\)” is an equivalence relation on the vertices of a graph. Its classes are the vertex sets of the components, so the components partition the vertex set.
Proof. A walk of length \(0\) joins \(v\) to itself; a walk can be reversed; and a \(uv\)-walk followed by a \(vw\)-walk is a \(uw\)-walk. So the relation is reflexive, symmetric and transitive. The subgraph induced by a class is connected, and it is maximal because any vertex joined by a walk to the class belongs to the class.
Theorem 1.2.6. If \(G\) is connected, then \(d\) is a metric on its vertex set.
Proof. Clearly \(d(u,v)\geqslant0\) with equality only if \(u=v\), and \(d(u,v)=d(v,u)\) because walks can be reversed. A shortest \(uw\)-walk followed by a shortest \(wv\)-walk is a \(uv\)-walk of length \(d(u,w)+d(w,v)\), which proves the triangle inequality. For digraphs symmetry fails, which is why a strongly connected digraph gives only a quasi-metric.
Definition 1.2.7. In a connected graph \(G\), the eccentricity of \(v\) is \(\mathrm{ecc}(v)=\max_{u}d(u,v)\). The radius and diameter are \[\mathrm{rad}(G)=\min_v\mathrm{ecc}(v),\qquad \mathrm{diam}(G)=\max_v\mathrm{ecc}(v).\] A vertex of minimum eccentricity is central, and the set of central vertices is the centre of \(G\).
Theorem 1.2.8. For every connected graph, \(\mathrm{rad}(G)\leqslant\mathrm{diam}(G)\leqslant2\,\mathrm{rad}(G)\).
Proof. The first inequality holds because a minimum is at most a maximum. For the second, let \(d(u,v)=\mathrm{diam}(G)\) and let \(z\) be central. Then \(d(u,v)\leqslant d(u,z)+d(z,v)\leqslant2\,\mathrm{ecc}(z)=2\,\mathrm{rad}(G)\).
Example 1.2.9. The path \(P_n\) with vertices \(1,2,\ldots,n\) has diameter \(n-1\) and radius \(\lfloor n/2\rfloor\). Its centre is \(\{(n+1)/2\}\) when \(n\) is odd and \(\{n/2,\,n/2+1\}\) when \(n\) is even. Both inequalities of Theorem 1.2.8 are sharp: \(K_n\) has radius and diameter \(1\), and \(P_{2k+1}\) has radius \(k\) and diameter \(2k\).
Definition 1.2.10. A vertex \(v\) of a graph \(G\) is a cut vertex if deleting it increases the number of components, and an edge \(e\) is a bridge (or cut edge) if deleting it increases the number of components.
Lemma 1.2.11. An edge is a bridge if and only if it lies on no cycle.
Proof. Let \(e=uv\). If \(e\) lies on a cycle, the rest of the cycle is a \(uv\)-path avoiding \(e\), so any walk that used \(e\) can be rerouted and deleting \(e\) disconnects nothing. Conversely, if deleting \(e\) does not separate \(u\) from \(v\), a \(uv\)-path in \(G-e\) together with \(e\) forms a cycle through \(e\).
Proposition 1.2.12. Deleting a bridge increases the number of components by exactly one.
Proof. Only the component \(C\) containing the bridge \(uv\) can change. Every vertex of \(C\) is joined to \(u\) by a path in \(C\); if this path does not use \(uv\), the vertex stays with \(u\), and otherwise its part after the bridge joins it to \(v\). So \(C-uv\) has at most two components, and it has two because \(uv\) is a bridge.
Definition 1.2.13. A graph is bipartite if its vertices can be split into two sets \(V_1,V_2\) such that every edge has one end in each set. The pair \((V_1,V_2)\) is a bipartition.
Lemma 1.2.14. Every closed walk of odd length contains a cycle of odd length.
Proof. Induct on the length. A closed walk of odd length with no repeated vertex other than its ends is an odd cycle. Otherwise some vertex \(w\) appears twice in the middle, and the walk splits at \(w\) into two shorter closed walks whose lengths add up to an odd number. One of them is odd, and the induction hypothesis applies to it.
Dénes Kőnig (1884–1944)
Hungarian mathematician in Budapest. His Theorie der endlichen und unendlichen Graphen (1936) was the first textbook of graph theory; it contains the characterisation of bipartite graphs below.
Theorem 1.2.15 (Kőnig). A graph is bipartite if and only if it has no cycle of odd length.
Proof. Going around a cycle in a bipartite graph we change sides at every step, and we return to the starting side only after an even number of steps. Conversely, suppose \(G\) has no odd cycle; we may assume it is connected. Fix a vertex \(z\) and put \(v\) in \(V_1\) if \(d(z,v)\) is even and in \(V_2\) otherwise. If an edge \(uv\) joined two vertices of the same set, a shortest \(zu\)-path, the edge \(uv\) and a shortest \(vz\)-path would form a closed walk of odd length \(d(z,u)+1+d(z,v)\). By Lemma 1.2.14 \(G\) would contain an odd cycle, a contradiction.
Remark 1.2.16. Lemma 1.2.14 has no even analogue. Two triangles sharing one vertex contain a closed walk of length \(6\) through the shared vertex, but no cycle of even length at all.
from collections import deque
def bfs(adj, s):
"""Distances from s to every vertex reachable from s."""
dist = {s: 0}
q = deque([s])
while q:
v = q.popleft()
for u in adj[v]:
if u not in dist:
dist[u] = dist[v] + 1
q.append(u)
return dist
def measures(adj):
ecc = {v: max(bfs(adj, v).values()) for v in adj}
r, d = min(ecc.values()), max(ecc.values())
return r, d, sorted(v for v in adj if ecc[v] == r)
def bipartition(adj):
"""Return the two sides, or None if there is an odd cycle (connected graphs)."""
dist = bfs(adj, next(iter(adj)))
if any((dist[u] - dist[v]) % 2 == 0 for v in adj for u in adj[v]):
return None
return [v for v in adj if dist[v] % 2 == 0], [v for v in adj if dist[v] % 2]
def path(n): return {v: [u for u in (v - 1, v + 1) if 1 <= u <= n] for v in range(1, n + 1)}
petersen = {i: [] for i in range(10)}
for i in range(5):
for a, b in ((i, (i + 1) % 5), (i, i + 5), (i + 5, (i + 2) % 5 + 5)):
petersen[a].append(b); petersen[b].append(a)
print("P6:", measures(path(6)), bipartition(path(6)))
print("P7:", measures(path(7)))
print("Petersen:", measures(petersen)[:2], "bipartite:", bipartition(petersen) is not None)
The program computes distances by breadth-first search, the standard method for unweighted graphs, and prints radius, diameter and centre. It confirms Example 1.2.9 for \(P_6\) and \(P_7\) and finds that the Petersen graph of Section 1.5 has radius and diameter \(2\) and is not bipartite.
Exercise 1.2.1 Pure
Prove that a connected graph on \(n\) vertices has at least \(n-1\) edges.
Add the edges one at a time to the empty graph on \(n\) vertices and watch \(\kappa\).
Adding an edge lowers the number of components by at most one.
Exercise 1.2.2 Pure Math Olympiad
Prove that a disconnected graph on \(n\) vertices has at most \(\binom{n-1}2\) edges, and find all graphs attaining this bound.
If the components have \(n_1\) and \(n-n_1\) vertices, there are no edges between them.
Compare \(\binom{n_1}2+\binom{n-n_1}2\) with \(\binom{n-1}2\).
Exercise 1.2.3 Pure
Prove that for every graph \(G\), either \(G\) or its complement (Section 1.4) is connected.
If \(G\) is disconnected, take \(u,v\) in \(\overline G\). Either they are in different components of \(G\), or both are adjacent in \(\overline G\) to a vertex of another component.
Exercise 1.2.4 Math Olympiad
Let \(G\) have \(n\) vertices and minimum degree \(\delta(G)\geqslant(n-1)/2\). Prove that \(G\) is connected and \(\mathrm{diam}(G)\leqslant2\).
Two non-adjacent vertices have together at least \(n-1\) neighbours among the other \(n-2\) vertices.
Exercise 1.2.5 Algorithm Informatics Olympiad
A grid of \(R\times C\) cells contains walls. A robot moves between neighbouring free cells. Design an \(O(RC)\) algorithm that finds the length of a shortest route between two given cells and the number of shortest routes.
Run breadth-first search on the graph of free cells.
The number of shortest routes to a cell is the sum of these numbers over its neighbours one step closer to the start.
Exercise 1.2.6 Code
Count the connected graphs on \([n]\) for \(n\leqslant5\) by brute force, using the programs of Sections 1.1 and 1.2. (The sequence returns in Section 1.10.)
Exercise 1.2.7 Pure
Prove that a graph is bipartite if and only if every subgraph \(H\) has an independent set (a set of pairwise non-adjacent vertices) with at least \(|V(H)|/2\) vertices.
For the converse, an odd cycle \(C_{2k+1}\) has no independent set with more than \(k\) vertices.
Draw a path on three vertices and label its middle vertex \(1\); then draw it again with the label \(2\) in the middle. As pairs \((V,E)\) the two graphs are different: one has the edge \(\{1,3\}\) and the other does not. As shapes they are the same. Counting problems come in two kinds according to which of these two points of view we take, and mixing them is the most common mistake in enumeration.
Definition 1.3.1. Let \(G=(V,E)\) and \(G'=(V',E')\) be graphs. A map \(\varphi:V\to V'\) is a homomorphism if \(uv\in E\) implies \(\varphi(u)\varphi(v)\in E'\). A bijection \(\varphi\) is an isomorphism if \(uv\in E \iff \varphi(u)\varphi(v)\in E'\). If an isomorphism exists, \(G\) and \(G'\) are isomorphic, written \(G\cong G'\). An isomorphism from \(G\) to itself is an automorphism, and the automorphisms of \(G\) form a group \(\mathrm{Aut}(G)\) under composition.
An isomorphism preserves adjacency and non-adjacency. A bijective homomorphism need not be an isomorphism: the identity map from the empty graph on \([2]\) to \(K_2\) is a bijective homomorphism.
Theorem 1.3.2. Isomorphism is an equivalence relation on graphs.
Proof. The identity is an isomorphism from \(G\) to itself; the inverse of an isomorphism is an isomorphism; the composition of two isomorphisms is an isomorphism.
The classes of this relation are called unlabeled graphs or isomorphism types. When we speak of “the graphs on \(n\) vertices” without naming the vertices, we mean the types; when the vertex set is a fixed set such as \([n]\), we mean the labeled graphs on that set. The counts behave very differently:
| \(n\) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|
| labeled graphs \(2^{\binom n2}\) | 1 | 2 | 8 | 64 | 1024 | 32768 | 2097152 | 268435456 |
| unlabeled graphs | 1 | 2 | 4 | 11 | 34 | 156 | 1044 | 12346 |
The second row has no closed formula; Pólya’s theorem in Chapter 3 gives a method to compute it. The bridge between the rows is the following theorem.
Theorem 1.3.3. Let \(G\) be a graph with vertex set \([n]\). The number of graphs on \([n]\) isomorphic to \(G\) is \[\frac{n!}{|\mathrm{Aut}(G)|}.\]
Proof. Each of the \(n!\) permutations \(\sigma\) of \([n]\) carries \(G\) to an isomorphic graph \(\sigma(G)\) on \([n]\), with edges \(\sigma(u)\sigma(v)\), and every graph on \([n]\) isomorphic to \(G\) arises in this way. Two permutations \(\sigma,\tau\) give the same graph exactly when \(\tau^{-1}\sigma\) is an automorphism of \(G\), that is, when \(\sigma\) lies in the coset \(\tau\,\mathrm{Aut}(G)\). So the \(n!\) permutations fall into classes of size \(|\mathrm{Aut}(G)|\), one class for each graph isomorphic to \(G\).
Example 1.3.4. The path \(P_n\) (\(n\geqslant2\)) has exactly two automorphisms, the identity and the reversal, so there are \(n!/2\) labeled paths on \([n]\). The cycle \(C_n\) (\(n\geqslant3\)) has \(2n\) automorphisms, the rotations and reflections of a regular \(n\)-gon, so there are \(n!/(2n)=(n-1)!/2\) labeled cycles. The star \(K_{1,n-1}\) has \((n-1)!\) automorphisms and \(n\) labeled copies. For \(n=4\): \(12\) paths and \(4\) stars, which together are the \(16\) labeled trees of Section 2.4.
Corollary 1.3.5. The number \(g_n\) of unlabeled graphs on \(n\) vertices satisfies \[g_n\geqslant\frac{2^{\binom n2}}{n!}.\]
Proof. By Theorem 1.3.3 each isomorphism type accounts for at most \(n!\) of the \(2^{\binom n2}\) labeled graphs.
Alfréd Rényi (1921–1970)
Hungarian mathematician, founder of the theory of random graphs with Paul Erdős. With Erdős he proved in 1963 that almost all graphs have no automorphism except the identity.
A mathematician is a device for turning coffee into theorems.
— attributed; it is often credited to Erdős, who credited it to Rényi
The bound of Corollary 1.3.5 is far from sharp for small \(n\) but correct in the limit: Erdős and Rényi showed that almost all graphs are asymmetric, that is, \(|\mathrm{Aut}(G)|=1\), and as a consequence \(g_n\sim2^{\binom n2}/n!\). We prove this in Chapter 6. The smallest asymmetric graphs have \(6\) vertices, and there are eight of them (Exercise 1.3.3).
from itertools import combinations, permutations
from math import factorial
def canon(n, edges, perms):
"""The lexicographically smallest relabeling: equal for isomorphic graphs."""
return min(tuple(sorted(tuple(sorted((p[u], p[v]))) for u, v in edges)) for p in perms)
def automorphisms(n, edges, perms):
E = {frozenset(e) for e in edges}
return sum(all(frozenset((p[u], p[v])) in E for u, v in edges) for p in perms)
for n in range(1, 6):
perms = list(permutations(range(n)))
pairs = list(combinations(range(n), 2))
types = {}
for mask in range(1 << len(pairs)):
E = [pairs[i] for i in range(len(pairs)) if mask >> i & 1]
types.setdefault(canon(n, E, perms), E)
total = sum(factorial(n) // automorphisms(n, E, perms) for E in types.values())
print(f"n={n}: {len(types)} unlabeled graphs; sum of n!/|Aut| = {total} = 2^C(n,2) = {2 ** len(pairs)}")
The program finds one representative of every isomorphism type for \(n\leqslant5\) by computing a canonical form, the smallest edge list over all relabelings, and then checks Theorem 1.3.3 by adding \(n!/|\mathrm{Aut}(G)|\) over the types. Trying all \(n!\) relabelings is hopeless beyond \(n\approx10\); Exercise 1.3.5 asks why, and Chapter 3 counts the types without listing them.
Exercise 1.3.1 Pure
Prove that \(|\mathrm{Aut}(C_n)|=2n\) for \(n\geqslant3\), and that \(|\mathrm{Aut}(K_{m,n})|=m!\,n!\) if \(m\neq n\) and \(2(n!)^2\) if \(m=n\).
An automorphism of \(C_n\) is decided by the image of vertex \(1\) and of one of its neighbours.
An automorphism of \(K_{m,n}\) maps each side to a side; when \(m=n\) the sides may be exchanged.
Exercise 1.3.2 Pure
The paw is a triangle with one pendant edge. How many graphs on \([4]\) are isomorphic to the paw?
Find \(|\mathrm{Aut}|\) of the paw and use Theorem 1.3.3.
Exercise 1.3.3 Math Olympiad Code
Prove that no graph with \(2\leqslant n\leqslant5\) vertices is asymmetric, and find an asymmetric graph with \(6\) vertices. Then confirm with a program that there are exactly \(8\) asymmetric graphs on \(6\) vertices.
A graph and its complement have the same automorphisms, so you may assume at most half of the possible edges are present.
Try a path \(P_5\) with one extra vertex joined to two of its vertices.
Exercise 1.3.4 Code
Write a program that computes \(|\mathrm{Aut}(G)|\) by backtracking: map the vertices one at a time and stop as soon as an adjacency fails. Use it to show that the Petersen graph has \(120\) automorphisms and the cube \(Q_3\) has \(48\).
Exercise 1.3.5 Computer Science
A computer checks \(10^9\) permutations per second. How long would the method of this section take to test whether two graphs on \(30\) vertices are isomorphic? Find out what is known about the complexity of graph isomorphism, and why it is believed to be easier than NP-complete problems.
Exercise 1.3.6 Pure
Use Corollary 1.3.5 to give a lower bound for the number of unlabeled graphs on \(10\) vertices. (The true number is \(12\,005\,168\).)
Compute \(2^{45}/10!\) and round up.
Exercise 1.3.7 Pure Math Olympiad
A tournament is a digraph in which every two vertices are joined by exactly one arc. Show that there are \(2^{\binom n2}\) tournaments on \([n]\), and find the number of unlabeled tournaments on \(4\) vertices by drawing them.
A set has subsets; a graph has subgraphs. Because a graph has two kinds of elements, vertices and edges, there are several natural ways to take a part of it, and each gives its own counting problem.
Definition 1.4.1. A graph \(H=(V',E')\) is a subgraph of \(G=(V,E)\) if \(V'\subseteq V\) and \(E'\subseteq E\). It is spanning if \(V'=V\). For \(U\subseteq V\), the induced subgraph \(G[U]\) has vertex set \(U\) and all edges of \(G\) with both ends in \(U\). For \(F\subseteq E\), the edge-induced subgraph \(G[F]\) has edge set \(F\) and the ends of these edges as vertices. We write \(G-v\) and \(G-e\) for the graphs obtained by deleting a vertex (with its edges) or an edge.
The counts are immediate: \(G\) has \(2^{|E|}\) spanning subgraphs, one for each set of edges, and \(2^{|V|}\) induced subgraphs, one for each set of vertices. Counting the subgraphs that have a given property, for example the connected spanning subgraphs or the spanning trees, is where the real work begins.
Definition 1.4.2. Let \(H\) be a graph. A graph \(G\) is \(H\)-free if no induced subgraph of \(G\) is isomorphic to \(H\).
Thus a triangle-free graph has no triangle at all, since a triangle in a graph is always induced. A square-free graph in this induced sense may contain a \(4\)-cycle, but every \(4\)-cycle in it has a chord. In extremal graph theory (Chapter 7) “\(H\)-free” often means “no subgraph isomorphic to \(H\)”; we will say so when we use that meaning.
Definition 1.4.3. The complement \(\overline G\) of a graph \(G\) has the same vertices, and two distinct vertices are adjacent in \(\overline G\) exactly when they are not adjacent in \(G\). A graph is self-complementary if \(G\cong\overline G\).
Theorem 1.4.4. There is a self-complementary graph on \(n\) vertices if and only if \(n\equiv0\) or \(1\pmod 4\).
Proof. If \(G\cong\overline G\) then \(G\) and \(\overline G\) have the same number of edges, so \(\binom n2\) is even, which happens exactly when \(n\) or \(n-1\) is divisible by \(4\).
Conversely, \(P_4\) and \(C_5\) are self-complementary, and so is \(K_1\). Suppose \(G\) is self-complementary, with an isomorphism \(\varphi:G\to\overline G\). Add four new vertices \(a,b,c,d\) forming a path \(a\,b\,c\,d\), and join \(b\) and \(c\) to every vertex of \(G\). The new graph \(G'\) has \(n+4\) vertices. Define \(\psi\) by \(\psi=\varphi\) on \(V(G)\) and \(\psi(a)=b\), \(\psi(b)=d\), \(\psi(c)=a\), \(\psi(d)=c\). One checks that \(\psi\) maps edges of \(G'\) to non-edges and non-edges to edges: inside \(G\) this is the property of \(\varphi\); among \(a,b,c,d\) it is the self-complementarity of \(P_4\) under this map; and the vertices \(b,c\), joined to all of \(G\), go to \(d,a\), joined to none of it. Starting from \(K_1\) and \(P_4\) we obtain all \(n\equiv1\) and \(n\equiv0\pmod 4\).
Example 1.4.5. Up to isomorphism there is one self-complementary graph on \(4\) vertices, the path \(P_4\), and there are two on \(5\) vertices, the cycle \(C_5\) and the bull (a triangle with two pendant edges at different vertices). On \(8\) and \(9\) vertices there are \(10\) and \(36\).
Definition 1.4.6. For graphs \(G\) and \(H\) with disjoint vertex sets, the union \(G\cup H\) has the vertices and edges of both; the join \(G+H\) adds all edges between \(V(G)\) and \(V(H)\). The Cartesian product \(G\,\square\,H\) has vertex set \(V(G)\times V(H)\), and \((g,h)\) is adjacent to \((g',h')\) if either \(g=g'\) and \(hh'\in E(H)\), or \(h=h'\) and \(gg'\in E(G)\).
For example \(K_{m,n}=\overline{K_m}+\overline{K_n}\), the wheel is \(W_n=C_n+K_1\), the grid is \(P_m\,\square\,P_n\), and the hypercube satisfies \(Q_n=Q_{n-1}\,\square\,K_2\). Many counting problems become easier for graphs built from smaller ones by these operations; the number of spanning trees of a product is a famous example (Chapter 3).
Stanisław Ulam (1909–1984)
Polish-American mathematician, co-inventor of the Monte Carlo method. He and Paul J. Kelly stated the reconstruction conjecture around 1941; Kelly proved the first results in 1957.
Give someone the \(n\) vertex-deleted subgraphs \(G-v\) of a graph \(G\), as unlabeled graphs, without saying which vertex was deleted from which. This multiset is the deck of \(G\) and its members are the cards. Does the deck determine \(G\)? The following lemma of Kelly shows that it determines a great deal, and its proof is pure double counting.
Lemma 1.4.7 (Kelly). Let \(G\) have \(n\) vertices and let \(H\) be a graph with \(h<n\) vertices. Write \(s(H,G)\) for the number of subgraphs of \(G\) isomorphic to \(H\). Then \[s(H,G)=\frac{1}{n-h}\sum_{v\in V(G)}s(H,G-v).\] In particular \(s(H,G)\) can be computed from the deck of \(G\).
Proof. Count pairs \((K,v)\) where \(K\) is a subgraph of \(G\) isomorphic to \(H\) and \(v\) is a vertex of \(G\) not in \(K\). Each \(K\) misses \(n-h\) vertices, giving \((n-h)\,s(H,G)\) pairs. For a fixed \(v\), the subgraphs \(K\) avoiding \(v\) are exactly the copies of \(H\) in \(G-v\), giving \(\sum_v s(H,G-v)\) pairs.
Corollary 1.4.8. The deck of a graph with \(n\geqslant3\) vertices determines its number of edges and its degree sequence.
Proof. Taking \(H=K_2\) in Lemma 1.4.7 gives \(|E(G)|=\frac1{n-2}\sum_v|E(G-v)|\). The card \(G-v\) has \(|E(G)|-\deg(v)\) edges, so each card tells us the degree of the vertex that was removed.
Research thread · The reconstruction conjecture
The conjecture of Kelly and Ulam says that every graph with at least \(3\) vertices is determined, up to isomorphism, by its deck. It is open as of 2026. It has been checked by computer for all graphs with at most \(11\) vertices (B. McKay, 1997), and proved for many families, including regular graphs, disconnected graphs and trees. Bollobás showed in 1990 that almost every graph is already determined by three suitably chosen cards. A first step: use Corollary 1.4.8 to prove that regular graphs are reconstructible, then do the same for disconnected graphs.
Reading: J. A. Bondy, A graph reconstructor’s manual, in Surveys in Combinatorics, 1991; J. Lauri and R. Scapellato, Topics in Graph Automorphisms and Reconstruction, 2nd ed., 2016.
from itertools import combinations
import random
def triangles(V, E):
return sum(1 for a, b, c in combinations(sorted(V), 3) if {(a, b), (a, c), (b, c)} <= E)
random.seed(1)
n = 9
V = set(range(n))
E = {(a, b) for a, b in combinations(range(n), 2) if random.random() < 0.5}
deck_sum = 0
for v in V: # the card G - v
Vv = V - {v}
Ev = {e for e in E if v not in e}
deck_sum += triangles(Vv, Ev)
print("triangles in G:", triangles(V, E))
print("from the deck: ", deck_sum / (n - 3)) # Kelly's lemma with H = K3
The program builds a random graph on \(9\) vertices and recovers its number of triangles from its nine cards, as Lemma 1.4.7 with \(H=K_3\) promises.
Exercise 1.4.1 Pure
How many spanning subgraphs of \(K_4\) are connected?
A spanning subgraph of \(K_4\) is a graph on \([4]\). List the disconnected ones by the sizes of their components.
Exercise 1.4.2 Pure
How many graphs on \([4]\) are self-complementary?
By Example 1.4.5 they are the labeled copies of \(P_4\).
Exercise 1.4.3 Math Olympiad
Prove that a self-complementary graph with at least two vertices is connected and has diameter \(2\) or \(3\).
Use the exercise of Section 1.2: \(G\) or \(\overline G\) is connected.
If \(\mathrm{diam}(G)\geqslant4\), show that \(\mathrm{diam}(\overline G)\leqslant2\).
Exercise 1.4.4 Code
Write a program that finds all self-complementary graphs on \(5\) vertices up to isomorphism.
Exercise 1.4.5 Pure
Prove that \(|E(G\,\square\,H)|=|V(G)|\,|E(H)|+|V(H)|\,|E(G)|\) and deduce that \(Q_n\) has \(n2^{n-1}\) edges.
Exercise 1.4.6 Research Project Code
A small research project: what does the deck know?
Write a program that computes the deck of a graph as a sorted list of canonical forms (Section 1.3).
Check that for \(3\leqslant n\leqslant6\) no two non-isomorphic graphs have the same deck.
Prove that a graph with \(n\geqslant3\) vertices is connected if and only if at least two of its cards are connected. Deduce that the deck determines connectivity.
Prove that the deck determines the number of spanning subgraphs of \(G\) isomorphic to any given disconnected graph \(F\) on \(n\) vertices.
Open-ended: read how (d) leads to the theorem of Tutte that the number of spanning trees, and even the whole Tutte polynomial (Chapter 4), is determined by the deck. Then try the edge deck, the multiset of graphs \(G-e\), and read about the edge reconstruction conjecture.
For (c): a connected graph has at least two vertices that are not cut vertices, for instance two leaves of a spanning tree.
For (c), conversely: if \(G\) is disconnected and \(G-v\) is connected, then \(v\) is isolated.
For (d): count, with Lemma 1.4.7, the copies in \(G\) of each component of \(F\), then correct for copies that overlap (this is Kocay’s lemma, 1981).
Before counting anything in general it pays to know a collection of well-understood graphs by heart. They test our definitions, suggest conjectures and supply counterexamples. This section is a small gallery; for each graph we give its order, size and number of automorphisms, which by Theorem 1.3.3 determines how many labeled copies it has.
Definition 1.5.1. The empty graph \(\overline{K_n}\) has \(n\) vertices and no edges, and its complement, the complete graph \(K_n\), has all \(\binom n2\) edges. A tournament is an orientation of \(K_n\): every pair of vertices is joined by exactly one arc. There are \(2^{\binom n2}\) tournaments on \([n]\).
Definition 1.5.2. A graph is complete \(r\)-partite, written \(K_{n_1,\ldots,n_r}\), if its vertices are split into \(r\) non-empty classes of sizes \(n_1,\ldots,n_r\), with no edge inside a class and every edge between different classes. A graph is \(r\)-partite if it is a subgraph of a complete \(r\)-partite graph on the same vertices. \(K_{1,n}\) is the star \(S_n\), and \(K_{1,3}\) is the claw.
With \(n=n_1+\cdots+n_r\), a vertex in the \(i\)-th class has degree \(n-n_i\), so by the handshake lemma \(K_{n_1,\ldots,n_r}\) has \(\frac12\sum_i n_i(n-n_i)=\sum_{i<j}n_in_j\) edges.
Definition 1.5.3. The path \(P_n\) has vertices \(1,\ldots,n\) and edges \(\{i,i+1\}\); the cycle \(C_n\) (\(n\geqslant3\)) adds the edge \(\{n,1\}\). The wheel \(W_n=C_n+K_1\) joins a new hub to every vertex of \(C_n\).
Definition 1.5.4. The hypercube \(Q_n\) has as vertices the \(2^n\) binary words of length \(n\), two words being adjacent when they differ in exactly one position. Every vertex has degree \(n\), so \(Q_n\) has \(n2^{n-1}\) edges.
Theorem 1.5.5. \(Q_n\) is bipartite, and for \(n\geqslant2\) it has a cycle through all of its vertices.
Proof. Put the words with an even number of ones on one side and the others on the other side; an edge changes one digit, so it changes the parity. For the cycle we use induction. \(Q_2\) is a \(4\)-cycle. Suppose \(c_1,\ldots,c_{2^n}\) is a cycle through all words of length \(n\). Appending \(0\) to each word and then appending \(1\) in the reverse order gives \[c_10,\ c_20,\ \ldots,\ c_{2^n}0,\ c_{2^n}1,\ \ldots,\ c_21,\ c_11,\] a cycle through all words of length \(n+1\).
William Rowan Hamilton (1805–1865)
Irish mathematician and physicist, inventor of the quaternions. In 1857 he invented the icosian game: find a cycle through all twenty vertices of a dodecahedron.
A cycle through every vertex of a graph is called a Hamiltonian cycle after Hamilton’s game. The cycle constructed in Theorem 1.5.5 is the reflected binary Gray code, used in engineering to list binary words so that consecutive words differ in one digit.
Julius Petersen (1839–1910)
Danish mathematician. The graph that carries his name appeared in his 1898 paper Sur le théorème de Tait as a counterexample; it had been drawn earlier by A. B. Kempe.
Definition 1.5.6. The Petersen graph has as vertices the \(2\)-element subsets of \([5]\), two subsets being adjacent when they are disjoint.
Proposition 1.5.7. The Petersen graph has \(10\) vertices and \(15\) edges, is \(3\)-regular, has girth \(5\) and diameter \(2\), and has no Hamiltonian cycle. Its automorphism group is the symmetric group \(S_5\), of order \(120\).
Proof. There are \(\binom52=10\) subsets, and each is disjoint from \(\binom32=3\) others, which gives \(3\)-regularity and, by the handshake lemma, \(15\) edges. Two adjacent vertices are disjoint pairs, say \(\{a,b\}\) and \(\{c,d\}\); a common neighbour would be a pair inside the one-element set \([5]\setminus\{a,b,c,d\}\), so there is none and there is no triangle. Two non-adjacent vertices share an element, say \(\{a,b\}\) and \(\{a,c\}\); their common neighbours are the pairs inside \([5]\setminus\{a,b,c\}\), and there is exactly one. Hence the diameter is \(2\), and there is no \(4\)-cycle, since its opposite vertices would have two common neighbours. The cycle \(12,34,51,23,45\) shows that the girth is \(5\). Every permutation of \([5]\) induces an automorphism; that there are no others, and that there is no Hamiltonian cycle, are Exercises 1.5.3 and 1.5.4.
The table collects the data of the gallery. The last column is the number of labeled copies on a fixed vertex set, computed with Theorem 1.3.3.
| Graph | Order | Size | \(\lvert\mathrm{Aut}\rvert\) | Labeled copies |
|---|---|---|---|---|
| \(K_n\) | \(n\) | \(\binom n2\) | \(n!\) | \(1\) |
| \(K_{m,n}\), \(m\neq n\) | \(m+n\) | \(mn\) | \(m!\,n!\) | \(\binom{m+n}{m}\) |
| \(K_{n,n}\) | \(2n\) | \(n^2\) | \(2(n!)^2\) | \(\frac12\binom{2n}{n}\) |
| \(S_n=K_{1,n}\), \(n\geqslant2\) | \(n+1\) | \(n\) | \(n!\) | \(n+1\) |
| \(P_n\), \(n\geqslant2\) | \(n\) | \(n-1\) | \(2\) | \(n!/2\) |
| \(C_n\), \(n\geqslant3\) | \(n\) | \(n\) | \(2n\) | \((n-1)!/2\) |
| \(W_n\), \(n\geqslant4\) | \(n+1\) | \(2n\) | \(2n\) | \((n+1)!/(2n)\) |
| \(Q_n\) | \(2^n\) | \(n2^{n-1}\) | \(2^n\,n!\) | \((2^n)!/(2^n n!)\) |
| Petersen | \(10\) | \(15\) | \(120\) | \(30240\) |
from itertools import combinations
def automorphism_count(adj):
"""Count automorphisms by extending a partial map one vertex at a time."""
V = sorted(adj)
nbr = {v: set(adj[v]) for v in V}
def extend(i, f, used):
if i == len(V):
return 1
v, total = V[i], 0
for w in V:
if w in used or len(nbr[w]) != len(nbr[v]):
continue
if all((u in nbr[v]) == (f[u] in nbr[w]) for u in V[:i]):
f[v] = w; used.add(w)
total += extend(i + 1, f, used)
del f[v]; used.discard(w)
return total
return extend(0, {}, set())
def from_edges(V, E):
adj = {v: [] for v in V}
for a, b in E:
adj[a].append(b); adj[b].append(a)
return adj
pairs = [frozenset(p) for p in combinations(range(1, 6), 2)]
gallery = {
"K5": from_edges(range(5), combinations(range(5), 2)),
"C6": from_edges(range(6), [(i, (i + 1) % 6) for i in range(6)]),
"W5": from_edges(range(6), [(i, (i + 1) % 5) for i in range(5)] + [(i, 5) for i in range(5)]),
"Q3": from_edges(range(8), [(x, x ^ (1 << k)) for x in range(8) for k in range(3) if x < x ^ (1 << k)]),
"Petersen": from_edges(pairs, [(p, q) for p, q in combinations(pairs, 2) if not p & q]),
}
for name, adj in gallery.items():
n = len(adj); m = sum(map(len, adj.values())) // 2
print(f"{name:9} order {n:2} size {m:2} |Aut| = {automorphism_count(adj)}")
The program counts automorphisms by building them vertex by vertex and abandoning a partial map as soon as it breaks an adjacency. It confirms the table for \(K_5\), \(C_6\), \(W_5\), \(Q_3\) and the Petersen graph in a fraction of a second, although the Petersen graph has \(10!=3\,628\,800\) permutations.
Research thread · Counting Hamiltonian cycles of the hypercube
By Theorem 1.5.5 every hypercube \(Q_n\) with \(n\geqslant2\) has a Hamiltonian cycle; but how many? The numbers for \(n=2,3,4\) are \(1\), \(6\) and \(1344\), and exact values are known only for a few more \(n\) (see OEIS A066037). No formula, recurrence or precise asymptotic estimate is known. A first step: write a program that confirms \(6\) and \(1344\), then look up the known lower and upper bounds and compare them for \(n=5\).
Reading: The On-Line Encyclopedia of Integer Sequences, entry A066037, and the references given there.
Exercise 1.5.1 Pure
How many edges does \(K_{2,3,4}\) have?
Exercise 1.5.2 Pure
Prove that \(\mathrm{diam}(Q_n)=n\) and that every two vertices at distance \(k\) are joined by exactly \(k!\) shortest paths.
The distance between two words is the number of positions in which they differ.
A shortest path flips the differing positions one at a time, in some order.
Exercise 1.5.3 Pure
Show that \(|\mathrm{Aut}(Q_n)|=2^n\,n!\), and that the Petersen graph has no automorphisms other than those induced by permutations of \([5]\).
Translations \(x\mapsto x\oplus a\) and permutations of the positions are automorphisms.
An automorphism fixing \(0\cdots0\) permutes its \(n\) neighbours, and this permutation decides it.
Exercise 1.5.4 Math Olympiad Code
Prove that the Petersen graph has no Hamiltonian cycle. Then confirm it with a program that searches all cycles from a fixed vertex.
Draw the graph as an outer \(5\)-cycle, an inner pentagram and five spokes. A Hamiltonian cycle uses an even number of spokes.
Two spokes and four spokes both lead to a contradiction with the girth.
Exercise 1.5.5 Pure
How many graphs on \([10]\) are isomorphic to the Petersen graph?
Exercise 1.5.6 Math Olympiad
Prove that every tournament has a Hamiltonian path, a directed path through all vertices. (Rédei, 1934.)
Induction: insert the new vertex \(v\) into a Hamiltonian path \(u_1\to\cdots\to u_{n}\) of the rest.
Find the first \(i\) with \(v\to u_i\).
Exercise 1.5.7 Code Algorithm
Count the Hamiltonian cycles of \(Q_4\) by a backtracking search, and explain why the same program cannot reach \(Q_6\).
Trees are the simplest connected graphs and the most counted ones. Two of the running problems of this book are about trees, so we collect their basic properties carefully.
Definition 1.6.1. A forest is a graph with no cycle, and a tree is a connected forest. A vertex of degree \(1\) in a tree is a leaf.
Lemma 1.6.2. Every tree with at least two vertices has at least two leaves.
Proof. Take a longest path \(u_0u_1\cdots u_k\) in the tree, with \(k\geqslant1\). If \(u_0\) had a neighbour other than \(u_1\), that neighbour would either lie on the path, creating a cycle, or lie off it, giving a longer path. So \(u_0\) is a leaf, and so is \(u_k\).
Theorem 1.6.3. For a graph \(T\) with \(n\) vertices the following are equivalent:
Proof. (1)\(\Rightarrow\)(2),(3): by Lemma 1.6.2, delete a leaf and use induction; a tree on one vertex has no edge. (2)\(\Rightarrow\)(1): a connected graph with a cycle stays connected after deleting an edge of the cycle (Lemma 1.2.11); repeat until no cycle is left, reaching a tree with fewer than \(n-1\) edges unless no edge was deleted. (3)\(\Rightarrow\)(1): a forest with \(k\) components, each a tree, has \(n-k\) edges by (1)\(\Rightarrow\)(2) applied to each component; so \(k=1\). (1)\(\Leftrightarrow\)(4): two different paths between the same vertices contain a cycle, and a cycle gives two paths between any two of its vertices. (1)\(\Leftrightarrow\)(5) is Lemma 1.2.11: every edge is a bridge exactly when no edge lies on a cycle. (4)\(\Leftrightarrow\)(6): adding \(uv\) closes a cycle with each \(uv\)-path.
Corollary 1.6.4. A forest with \(n\) vertices and \(k\) components has \(n-k\) edges. Every connected graph contains a spanning tree: a spanning subgraph that is a tree.
Proof. The first statement was shown in the proof above. For the second, delete edges lying on cycles one at a time; the graph stays connected and eventually has no cycle.
Camille Jordan (1838–1922)
French mathematician, known for the Jordan curve theorem and the Jordan normal form. In 1869 he proved that the centre of a tree has one or two vertices.
Theorem 1.6.5 (Jordan, 1869). The centre of a tree is a single vertex or two adjacent vertices.
Proof. Deleting all leaves of a tree \(T\) with at least three vertices gives a tree \(T'\). Every vertex farthest from a given vertex is a leaf, so \(\mathrm{ecc}_{T'}(v)=\mathrm{ecc}_T(v)-1\) for every \(v\) in \(T'\), and \(T\) and \(T'\) have the same centre. Repeating, we reach a tree with one or two vertices, whose centre is all of it.
Definition 1.6.6. A rooted tree is a tree with one distinguished vertex, its root. Every non-root vertex \(v\) has a parent, the next vertex on the path from \(v\) to the root, and the vertices whose parent is \(v\) are its children. A plane tree is a rooted tree in which the children of every vertex are ordered.
Here are the first counts. Labeled trees on \([n]\) are counted by Cayley’s formula \(n^{n-2}\), proved in Section 2.4. Unlabeled trees have no closed formula; their numbers are found by Otter’s recursion in Chapter 4.
| \(n\) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| labeled trees \(n^{n-2}\) | 1 | 1 | 3 | 16 | 125 | 1296 | 16807 | 262144 | 4782969 | 100000000 |
| unlabeled trees | 1 | 1 | 1 | 2 | 3 | 6 | 11 | 23 | 47 | 106 |
def canonical(adj, root, parent=None):
"""AHU code of the subtree at root: equal codes mean isomorphic rooted trees."""
return "(" + "".join(sorted(canonical(adj, c, root) for c in adj[root] if c != parent)) + ")"
def centre(adj):
layer = [v for v in adj if len(adj[v]) <= 1]
deg = {v: len(adj[v]) for v in adj}
left = len(adj)
while left > 2:
nxt = []
for v in layer:
left -= 1
for u in adj[v]:
deg[u] -= 1
if deg[u] == 1:
nxt.append(u)
layer = nxt
return layer
def tree_code(adj):
"""Canonical form of an unrooted tree: root it at its centre (Jordan's theorem)."""
return min(canonical(adj, c) for c in centre(adj))
def trees_from_pruefer(n):
"""Decode every Pruefer word (Section 2.4) to get every labeled tree on 1..n."""
from itertools import product
for word in product(range(1, n + 1), repeat=n - 2):
word = list(word)
degree = {v: 1 for v in range(1, n + 1)}
for a in word:
degree[a] += 1
adj = {v: [] for v in range(1, n + 1)}
for a in word:
leaf = min(v for v in degree if degree[v] == 1)
adj[leaf].append(a); adj[a].append(leaf)
degree[leaf] = 0; degree[a] -= 1
u, v = [x for x in degree if degree[x] == 1]
adj[u].append(v); adj[v].append(u)
yield adj
for n in range(3, 9):
codes = {tree_code(adj) for adj in trees_from_pruefer(n)}
print(n, "labeled:", n ** (n - 2), " unlabeled:", len(codes))
The program generates all labeled trees for \(n\leqslant8\) and sorts them into isomorphism types. To decide when two trees are isomorphic it roots each tree at its centre, which is legitimate by Theorem 1.6.5, and computes the AHU code of Aho, Hopcroft and Ullman: a leaf is “()”, and a vertex is its children’s codes, sorted and wrapped in brackets. The output reproduces the second row of the table up to \(n=8\).
Exercise 1.6.1 Pure
Let \(n_d\) be the number of vertices of degree \(d\) in a tree with at least two vertices. Prove that the number of leaves is \(n_1=2+\sum_{d\geqslant3}(d-2)n_d\). How many leaves has a tree with exactly three vertices of degree \(3\), one of degree \(4\), and all other vertices of degree \(1\) or \(2\)?
Combine \(\sum_d n_d=n\) and \(\sum_d d\,n_d=2(n-1)\).
Exercise 1.6.2 Pure
Prove that a tree with maximum degree \(\Delta\) has at least \(\Delta\) leaves.
Follow a path out of the vertex of maximum degree through each of its neighbours until it ends.
Exercise 1.6.3 Pure
How many spanning trees has the cycle \(C_n\)? the wheel \(W_4\)?
Every spanning tree of \(C_n\) is \(C_n\) minus one edge.
For \(W_4\), sort the spanning trees by the number of spokes they use.
Exercise 1.6.4 Algorithm Informatics Olympiad
Prove that the following algorithm finds the diameter of a tree in linear time: from any vertex \(s\) find a farthest vertex \(u\), then from \(u\) find a farthest vertex \(w\); return \(d(u,w)\).
Show that \(u\) is an end of some longest path, using the uniqueness of paths in trees.
Exercise 1.6.5 Code
Extend the program of this section to \(n=10\). Generating all \(10^8\) labeled trees is too slow; instead generate unlabeled trees directly by adding a leaf in all possible ways to every tree on \(n-1\) vertices and removing duplicates by their codes.
Exercise 1.6.6 Pure Math Olympiad
Prove that every tree on \(n\) vertices is a subgraph of every graph with minimum degree at least \(n-1\).
Embed the tree leaf by leaf, removing leaves in the order given by Lemma 1.6.2 and adding them back.
Exercise 1.6.7 Pure
A centroid of a tree is a vertex whose removal leaves components with as few vertices as possible. Prove that every tree has one centroid or two adjacent centroids, and give a tree whose centre and centroid are far apart.
A graph is a stage on which many kinds of structures live: sets of edges that do not touch, sets of vertices that do not see each other, ways of colouring, ways of walking. Almost every counting question in this book asks how many structures of one of these kinds a graph carries. This section introduces them and computes the answer for the simplest graphs; the rest of the book is about the harder graphs.
Definition 1.7.1. A matching in a graph is a set of edges no two of which share an end. It is perfect if every vertex is an end of one of its edges. An independent set is a set of pairwise non-adjacent vertices, and a clique is a set of pairwise adjacent vertices.
Proposition 1.7.2. The number of perfect matchings of \(K_{2m}\) is \((2m-1)!!=(2m-1)(2m-3)\cdots3\cdot1\), and the number of perfect matchings of \(K_{n,n}\) is \(n!\).
Proof. In \(K_{2m}\) the vertex \(1\) can be matched in \(2m-1\) ways, and what remains is a \(K_{2m-2}\); induction finishes the proof. In \(K_{n,n}\) a perfect matching assigns to each vertex on the left a different vertex on the right, that is, a permutation.
Definition 1.7.3. A proper \(k\)-colouring of a graph \(G\) assigns to each vertex one of \(k\) colours so that adjacent vertices get different colours. The number of proper \(k\)-colourings is denoted \(P(G,k)\); as a function of \(k\) it is the chromatic polynomial of \(G\). The chromatic number \(\chi(G)\) is the least \(k\) with \(P(G,k)>0\).
George David Birkhoff (1884–1944)
American mathematician at Harvard. He introduced the chromatic polynomial in 1912, hoping to prove the four colour conjecture by showing that \(P(G,4)>0\) for every planar map.
That \(P(G,k)\) is a polynomial in \(k\) is not obvious; Chapter 2 proves it with inclusion–exclusion and Chapter 4 with deletion–contraction. For simple graphs we can compute it directly.
Proposition 1.7.4. For every \(k\):
Proof. (1) The vertices of \(K_n\) need different colours: colour them one by one. (2) There are no constraints. (3) Induct on \(n\): remove a leaf \(\ell\); colour the tree \(T-\ell\) in \(k(k-1)^{n-2}\) ways, then give \(\ell\) any colour except the colour of its only neighbour. (4) The colourings of the path \(P_n\) number \(k(k-1)^{n-1}\) by (3). They split into those in which the two ends get different colours, which are exactly the colourings of \(C_n\), and those in which the ends get the same colour, which correspond to the colourings of \(C_{n-1}\) obtained by merging the two ends. So \(P(C_n,k)=k(k-1)^{n-1}-P(C_{n-1},k)\), and the formula follows by induction from \(P(C_3,k)=k(k-1)(k-2)\).
Example 1.7.5. \(P(C_4,k)=(k-1)^4+(k-1)=k^4-4k^3+6k^2-3k\). With \(3\) colours this gives \(18\) colourings of the square; with \(2\) colours it gives \(2\), the two ways of colouring the square like a chessboard.
Definition 1.7.6. A Hamiltonian cycle passes through every vertex exactly once. An Eulerian circuit is a closed trail that uses every edge exactly once. An orientation of \(G\) chooses a direction for every edge; it is acyclic if it creates no directed cycle.
The complete graph \(K_n\) has \((n-1)!/2\) Hamiltonian cycles, by Example 1.3.4, and every graph with \(m\) edges has \(2^m\) orientations. Here are the counts for three small graphs, computed by the program below. Each row of the table is a separate problem that the later chapters solve in general.
| Graph | perfect matchings | independent sets | \(P(G,3)\) | spanning trees | Hamiltonian cycles | acyclic orientations |
|---|---|---|---|---|---|---|
| \(C_6\) | 2 | 18 | 66 | 6 | 1 | 62 |
| \(Q_3\) | 9 | 35 | 114 | 384 | 6 | 1862 |
| Petersen | 6 | 76 | 120 | 2000 | 0 | 16680 |
from itertools import combinations
def graph(V, E):
adj = {v: set() for v in V}
for a, b in E:
adj[a].add(b); adj[b].add(a)
return adj
def perfect_matchings(adj, left=None):
left = set(adj) if left is None else left
if not left:
return 1
v = min(left)
return sum(perfect_matchings(adj, left - {v, u}) for u in adj[v] & left)
def independent_sets(adj, left=None):
left = sorted(adj) if left is None else left
if not left:
return 1
v, rest = left[0], left[1:]
return independent_sets(adj, rest) + independent_sets(adj, [u for u in rest if u not in adj[v]])
def colourings(adj, k):
V, colour = sorted(adj), {}
def go(i):
if i == len(V):
return 1
total = 0
for c in range(k):
if all(colour.get(u) != c for u in adj[V[i]]):
colour[V[i]] = c; total += go(i + 1); del colour[V[i]]
return total
return go(0)
def spanning_trees(adj):
V = sorted(adj); E = [(a, b) for a in V for b in adj[a] if a < b]
count = 0
for S in combinations(E, len(V) - 1):
parent = {v: v for v in V}
def find(x):
while parent[x] != x:
x = parent[x]
return x
ok = True
for a, b in S:
ra, rb = find(a), find(b)
if ra == rb:
ok = False; break
parent[ra] = rb
count += ok
return count
def hamiltonian_cycles(adj):
V = sorted(adj); s = V[0]; found = 0
def go(v, seen):
nonlocal found
if len(seen) == len(V):
found += s in adj[v]; return
for u in adj[v] - seen:
go(u, seen | {u})
go(s, {s})
return found // 2
def acyclic_orientations(adj):
# Stanley's theorem (Exercise 1.7.7): |P(G, -1)|, computed here by deletion-contraction.
def chrom(V, E, k):
if not E:
return k ** len(V)
(a, b), rest = E[0], E[1:]
merged = {tuple(sorted((a if x == b else x, a if y == b else y))) for x, y in rest}
merged = sorted(e for e in merged if e[0] != e[1])
return chrom(V, rest, k) - chrom(V - {b}, merged, k)
E = sorted((a, b) for a in adj for b in adj[a] if a < b)
return abs(chrom(set(adj), E, -1))
C6 = graph(range(6), [(i, (i + 1) % 6) for i in range(6)])
Q3 = graph(range(8), [(x, x ^ (1 << k)) for x in range(8) for k in range(3) if x < x ^ (1 << k)])
P = graph(range(10), [(i, (i + 1) % 5) for i in range(5)] + [(i, i + 5) for i in range(5)]
+ [(i + 5, (i + 2) % 5 + 5) for i in range(5)])
for name, G in (("C6", C6), ("Q3", Q3), ("Petersen", P)):
print(f"{name:9}", perfect_matchings(G), independent_sets(G), colourings(G, 3),
spanning_trees(G), hamiltonian_cycles(G), acyclic_orientations(G))
Every function in the program is a brute-force search, and each would take astronomically long on a graph with a few hundred vertices. Some of these counts have fast algorithms (spanning trees, through the Matrix-Tree Theorem of Chapter 3) and some almost certainly do not (perfect matchings in general graphs and Hamiltonian cycles, Chapter 6). Telling the two kinds apart is part of what it means to answer a counting question.
Lab · Count everything
The reader draws a small graph or picks one from the gallery. The lab shows its numbers of matchings, perfect matchings, independent sets, cliques, proper \(k\)-colourings for a chosen \(k\), spanning trees, Hamiltonian cycles and acyclic orientations, and highlights one example of each structure.
This lab is being built for the web edition.
Exercise 1.7.1 Pure
Prove Proposition 1.7.2 by a different argument: count the ordered lists \((a_1b_1,\ldots,a_mb_m)\) of edges forming a perfect matching of \(K_{2m}\) together with an orientation of each edge, in two ways.
One count is \((2m)!\). The other is the number of perfect matchings times \(m!\,2^m\).
Exercise 1.7.2 Pure
Use the formula for \(P(C_n,k)\) to find the number of ways to colour the five vertices of a pentagon with \(3\) colours so that neighbours differ.
Exercise 1.7.3 Pure Math Olympiad
Prove that the path \(P_n\) has \(F_{n+2}\) independent sets, where \(F_1=F_2=1\) and \(F_{k}=F_{k-1}+F_{k-2}\).
Split the independent sets by whether they contain the last vertex.
Exercise 1.7.4 Pure
Prove that \(K_{n,n}\) has \(\frac{n!\,(n-1)!}{2}\) Hamiltonian cycles for \(n\geqslant2\).
A Hamiltonian cycle alternates sides. Fix the starting vertex on the left and divide by the two directions.
Exercise 1.7.5 Code
Use the program of this section to count the Hamiltonian cycles of \(Q_3\) and the proper \(3\)-colourings of \(Q_3\). Then compute \(P(Q_3,k)\) for \(k=0,1,\ldots,7\) and find the polynomial by interpolation.
Exercise 1.7.6 Computer Science
Deciding whether a graph has a perfect matching takes polynomial time (Edmonds, 1965), but counting perfect matchings is #P-complete (Valiant, 1979). Deciding whether a graph has a Hamiltonian cycle is NP-complete. Explain these words, and explain why counting can be hard even when deciding is easy.
Exercise 1.7.7 Research Project Code
A small research project: acyclic orientations.
Write a program that counts the acyclic orientations of a graph by trying all \(2^m\) orientations.
Compute the numbers for \(K_n\), \(C_n\) and the trees on \(n\) vertices, for small \(n\), and guess formulas.
Compare your numbers with \(|P(G,-1)|\), the absolute value of the chromatic polynomial at \(-1\). State a conjecture and test it on the graphs of the table.
Prove your conjecture for trees and cycles. (The general theorem is due to R. Stanley, 1973; Chapter 4 proves it with deletion–contraction.)
Open-ended: what do \(|P(G,-2)|\) and \(|P(G,-3)|\) count?
For (b): \(K_n\) has \(n!\) acyclic orientations, one for each ordering of its vertices.
For (b): \(C_n\) has \(2^n-2\), all orientations except the two directed cycles.
This section collects the elementary counting principles that we use without comment in the rest of the book. Most readers have met them; we state them in the language of graphs so that the examples are already of the right kind.
Definition 1.8.1. Let \(A\) and \(B\) be finite sets.
The handshake lemma (Theorem 1.1.5) is double counting with \(A=V\), \(B=E\) and \(R\) the incidence relation; the count of labeled copies (Theorem 1.3.3) is the product rule applied to permutations; and Exercise 1.1.1 is the pigeonhole principle. Here is one more example of double counting, which has a graph in disguise.
Example 1.8.2. Count the pairs \((S,v)\) with \(S\subseteq[n]\) and \(v\in S\). Choosing \(S\) first gives \(\sum_k k\binom nk\); choosing \(v\) first gives \(n\,2^{n-1}\). So \(\sum_k k\binom nk=n2^{n-1}\). In the language of graphs: the sets \(S\) are the vertices of \(Q_n\), and \(n2^{n-1}\) is its number of edges, each edge joining a set \(S\ni v\) to \(S\setminus\{v\}\).
Proposition 1.8.3. Let \(n,k\geqslant0\).
Proof. (1) and (4) are the product rule; (2) follows because each \(k\)-subset is listed \(k!\) times among the words without repetition. For (3), a multiset of size \(k\) from \(\{1,\ldots,n\}\) is described by \(k\) stars and \(n-1\) bars, the bars separating the multiplicities of \(1,2,\ldots,n\); choosing the positions of the \(k\) stars among \(n+k-1\) places is a \(k\)-subset.
Example 1.8.4. A loopless multigraph on \([n]\) with \(m\) edges is a multiset of size \(m\) chosen from the \(\binom n2\) pairs. So there are \(\binom{\binom n2+m-1}{m}\) of them; on \([3]\) with \(5\) edges there are \(\binom75=21\).
Definition 1.8.5. A composition of \(n\) into \(k\) parts is a sequence \((a_1,\ldots,a_k)\) of positive integers with sum \(n\); it is weak if zeros are allowed. A partition of \(n\) is a composition whose order does not matter, written with \(a_1\geqslant a_2\geqslant\cdots\). The number of partitions of \(n\) is \(p(n)\).
Proposition 1.8.6. There are \(\binom{n-1}{k-1}\) compositions and \(\binom{n+k-1}{k-1}\) weak compositions of \(n\) into \(k\) parts, and \(2^{n-1}\) compositions of \(n\) in all (\(n\geqslant1\)).
Proof. Write \(n\) as a row of \(n\) ones and choose \(k-1\) of the \(n-1\) gaps between them to cut. A weak composition of \(n\) into \(k\) parts becomes a composition of \(n+k\) by adding \(1\) to every part. Summing over \(k\) gives \(\sum_k\binom{n-1}{k-1}=2^{n-1}\).
The twelvefold way organises twelve basic counting problems in one table. The idea goes back to Gian-Carlo Rota’s lectures; the name was suggested by Joel Spencer and made famous by Richard Stanley’s Enumerative Combinatorics.
Place \(k\) balls into \(n\) boxes. The balls may be distinguishable (labeled) or not, the boxes may be distinguishable or not, and we may require nothing, at most one ball per box (injective), or at least one ball per box (surjective). The twelve answers are:
| balls | boxes | any | at most one | at least one |
|---|---|---|---|---|
| labeled | labeled | \(n^k\) | \(n^{\underline k}\) | \(n!\,S(k,n)\) |
| unlabeled | labeled | \(\binom{n+k-1}{k}\) | \(\binom nk\) | \(\binom{k-1}{n-1}\) |
| labeled | unlabeled | \(\sum_{i=0}^{n}S(k,i)\) | \([k\leqslant n]\) | \(S(k,n)\) |
| unlabeled | unlabeled | \(\sum_{i=0}^{n}p_i(k)\) | \([k\leqslant n]\) | \(p_n(k)\) |
Here \(S(k,n)\) is the Stirling number of the second kind, the number of partitions of a \(k\)-set into \(n\) non-empty blocks (Section 1.9); \(p_i(k)\) is the number of partitions of \(k\) into exactly \(i\) parts; and \([k\leqslant n]\) is \(1\) if \(k\leqslant n\) and \(0\) otherwise. The labeled/unlabeled distinction of Section 1.3 is visible in every column. Graph theory supplies a natural reading of each entry: for instance, colouring the vertices of \(\overline{K_k}\) with \(n\) colours, all of them used, is the top right entry.
from itertools import product
from math import comb, factorial
from functools import lru_cache
@lru_cache(None)
def S(k, n): # Stirling numbers of the second kind
if k == n: return 1
if n == 0 or n > k: return 0
return n * S(k - 1, n) + S(k - 1, n - 1)
@lru_cache(None)
def p_exact(k, i): # partitions of k into exactly i parts
if k == 0 and i == 0: return 1
if k <= 0 or i <= 0: return 0
return p_exact(k - 1, i - 1) + p_exact(k - i, i)
def formulas(k, n):
fall = factorial(n) // factorial(n - k) if k <= n else 0
return [n ** k, fall, factorial(n) * S(k, n),
comb(n + k - 1, k), comb(n, k), comb(k - 1, n - 1) if k >= 1 else int(n == 0),
sum(S(k, i) for i in range(n + 1)), int(k <= n), S(k, n),
sum(p_exact(k, i) for i in range(n + 1)), int(k <= n), p_exact(k, n)]
def brute(k, n):
maps = list(product(range(n), repeat=k)) # ball -> box
inj = [f for f in maps if len(set(f)) == k]
sur = [f for f in maps if len(set(f)) == n]
def u_balls(fs): return {tuple(sorted(f)) for f in fs} # forget ball labels
def u_boxes(fs): # forget box labels
return {frozenset(frozenset(b for b in range(k) if f[b] == x) for x in range(n)) - {frozenset()} for f in fs}
def u_both(fs): return {tuple(sorted(len(blk) for blk in part)) for part in u_boxes(fs)}
out = []
for kind in (lambda fs: fs, u_balls, u_boxes, u_both):
out += [len(set(map(tuple, kind(fs))) if kind is not u_boxes else kind(fs)) for fs in (maps, inj, sur)]
return out
for k in range(0, 5):
for n in range(1, 5):
assert formulas(k, n) == brute(k, n), (k, n)
print("all twelve formulas agree with brute force for k <= 4, n <= 4")
print("k=4, n=3:", formulas(4, 3))
Exercise 1.8.1 Pure
In how many ways can the vertices of \(\overline{K_5}\) be coloured with \(3\) colours so that every colour is used?
Exercise 1.8.2 Pure
How many loopless multigraphs on \([4]\) have exactly \(3\) edges?
Use Example 1.8.4 with \(\binom42=6\) pairs.
Exercise 1.8.3 Math Olympiad
Prove that among any \(n+1\) numbers chosen from \([2n]\) two are coprime, and two are such that one divides the other.
Two consecutive integers are coprime; pair \(\{1,2\},\{3,4\},\ldots\).
Write each number as \(2^a\cdot q\) with \(q\) odd; there are only \(n\) odd parts \(q\).
Exercise 1.8.4 Pure Math Olympiad
Prove that the number of compositions of \(n\) into odd parts is the Fibonacci number \(F_n\).
Split by whether the last part is \(1\) or at least \(3\).
Exercise 1.8.5 Pure
A graph on \([n]\) is called a matching graph if every vertex has degree at most \(1\). Show that the number of matching graphs on \([n]\) with exactly \(k\) edges is \(\frac{n!}{(n-2k)!\,k!\,2^k}\).
Exercise 1.8.6 Code
Run the program of this section and extend it to \(k,n\leqslant5\). Which entry of the table is the slowest to compute by brute force, and why?
Exercise 1.8.7 Computer Science Algorithm
Design an algorithm that lists all \(2^n\) subsets of \([n]\) so that consecutive subsets differ in one element, using \(O(1)\) amortised time per subset. Relate it to Theorem 1.5.5.
The reflected Gray code changes the bit whose position is the number of trailing zeros of the step counter.
A small number of sequences appear again and again when we count graphs. Each of them counts a family of graphs directly, and knowing these graph models is often the quickest way to recognise a sequence when it appears in a new problem. This section is a reference; the proofs are short, and many are left as exercises.
We have met \(\binom nk\) as the number of graphs on \([n]\) that are a clique on \(k\) vertices plus isolated vertices, and \(\binom{\binom n2}{m}\) as the number of graphs with \(m\) edges. The basic identities are Pascal’s rule \(\binom nk=\binom{n-1}{k-1}+\binom{n-1}{k}\), the binomial theorem \((x+y)^n=\sum_k\binom nkx^ky^{n-k}\) and Vandermonde’s identity \(\binom{m+n}{k}=\sum_i\binom mi\binom n{k-i}\). Vandermonde’s identity counts \(k\)-subsets of the vertices of the disjoint union \(\overline{K_m}\cup\overline{K_n}\) according to how many vertices they take from each part.
James Stirling (1692–1770)
Scottish mathematician. The numbers named after him appear in his Methodus Differentialis (1730), as the coefficients that convert powers into falling factorials and back.
Definition 1.9.1. The Stirling number of the second kind \(S(n,k)\) is the number of partitions of \([n]\) into \(k\) non-empty blocks. The unsigned Stirling number of the first kind \(c(n,k)\) is the number of permutations of \([n]\) with exactly \(k\) cycles. The Bell number \(B_n=\sum_kS(n,k)\) is the number of partitions of \([n]\).
Proposition 1.9.2. For \(n,k\geqslant1\), \[S(n,k)=k\,S(n-1,k)+S(n-1,k-1),\qquad c(n,k)=(n-1)\,c(n-1,k)+c(n-1,k-1),\] with \(S(0,0)=c(0,0)=1\) and \(S(n,0)=c(n,0)=0\) for \(n\geqslant1\).
Proof. Remove the element \(n\). In a partition of \([n]\) into \(k\) blocks, either \(\{n\}\) is a block, and the rest is a partition of \([n-1]\) into \(k-1\) blocks, or \(n\) was added to one of the \(k\) blocks of a partition of \([n-1]\). In a permutation with \(k\) cycles, either \(n\) is a fixed point, or \(n\) was inserted into a cycle of a permutation of \([n-1]\) after one of its \(n-1\) elements.
Graph models. A partition of \([n]\) is the same thing as a cluster graph on \([n]\), a disjoint union of cliques: the blocks are the cliques. So \(B_n\) counts the cluster graphs on \([n]\) and \(S(n,k)\) those with \(k\) components, and \(p(n)\) counts the cluster graphs on \(n\) vertices up to isomorphism. A permutation \(\sigma\) of \([n]\) is the same as its functional digraph, with an arc \(i\to\sigma(i)\) for every \(i\); this digraph is a disjoint union of directed cycles, and \(c(n,k)\) counts those with \(k\) cycles.
Eugène Charles Catalan (1814–1894)
Belgian mathematician. He studied the numbers now named after him in 1838, in connection with ways of bracketing a product; Euler had met them a century earlier when counting triangulations of polygons.
The Catalan numbers \(\mathrm{Cat}_n=\frac1{n+1}\binom{2n}{n}\) count binary plane trees with \(n\) internal vertices (each internal vertex has an ordered left and right child), plane trees with \(n+1\) vertices, and triangulations of a convex \((n+2)\)-gon, which are maximal sets of non-crossing diagonals. They satisfy \(\mathrm{Cat}_{n+1}=\sum_{i=0}^{n}\mathrm{Cat}_i\,\mathrm{Cat}_{n-i}\): split a binary plane tree at its root.
The Fibonacci numbers \(F_1=F_2=1\), \(F_{n}=F_{n-1}+F_{n-2}\) count the independent sets of the path \(P_{n-2}\) (Exercise 1.7.3) and the perfect matchings of the ladder \(P_2\,\square\,P_{n-1}\).
The Eulerian number \(A(n,k)\) counts permutations of \([n]\) with exactly \(k\) descents, positions \(i\) with \(\sigma(i)>\sigma(i+1)\). In graph language: label the vertices of the path \(P_n\), taken in their natural order, by \(1,\ldots,n\) in some order, and orient every edge towards its larger label; \(A(n,k)\) counts the labelings in which exactly \(k\) edges point backwards. They satisfy \(A(n,k)=(k+1)A(n-1,k)+(n-k)A(n-1,k-1)\).
A derangement is a permutation with no fixed point; in graph language, a functional digraph with no loop, or a covering of the vertices of \(K_n\) by disjoint directed cycles of length at least \(2\). Their number is \(D_n=n!\sum_{i=0}^{n}\frac{(-1)^i}{i!}\), which we prove by inclusion–exclusion in Chapter 2, and it satisfies \(D_n=(n-1)(D_{n-1}+D_{n-2})\).
| sequence | \(n=0,1,2,\ldots\) | OEIS |
|---|---|---|
| Bell \(B_n\) | 1, 1, 2, 5, 15, 52, 203, 877, 4140 | A000110 |
| Catalan \(\mathrm{Cat}_n\) | 1, 1, 2, 5, 14, 42, 132, 429, 1430 | A000108 |
| Fibonacci \(F_n\) | 0, 1, 1, 2, 3, 5, 8, 13, 21 | A000045 |
| derangements \(D_n\) | 1, 0, 1, 2, 9, 44, 265, 1854, 14833 | A000166 |
| partitions \(p(n)\) | 1, 1, 2, 3, 5, 7, 11, 15, 22 | A000041 |
| \(S(n,k)\), by rows | 1; 0, 1; 0, 1, 1; 0, 1, 3, 1; 0, 1, 7, 6, 1 | A008277 |
| \(c(n,k)\), by rows | 1; 0, 1; 0, 1, 1; 0, 2, 3, 1; 0, 6, 11, 6, 1 | A132393 |
| Eulerian \(A(n,k)\), \(n\geqslant1\) | 1; 1, 1; 1, 4, 1; 1, 11, 11, 1 | A008292 |
From the authors’ research
D. Yaqubi and M. Mirzavaziri, Stirling-like sequences* (title to be confirmed)* · preprint
Many triangles in this section obey a recurrence of the form \(a(n,k)=f(n,k)\,a(n-1,k-1)+g(n,k)\,a(n-1,k)\). Our preprint develops a simple matrix tool that proves identities for all such triangles at once and recovers the classical identities for Stirling, Lah and binomial numbers as special cases. Chapter 4 returns to it. [Authors: add the preprint link.]
From the authors’ research
M. Mirzavaziri and coauthors, Latin Eulerian numbers* (title to be confirmed)* · preprint
Eulerian numbers count permutations by descents. Counting Latin squares by the number of ascents in each column gives a two-dimensional generalisation, the Latin Eulerian numbers; Latin squares of order \(n\) are the proper edge colourings of \(K_{n,n}\) with \(n\) colours. [Authors: add a two-sentence summary of the main result and the preprint link.]
from math import comb, factorial
from itertools import combinations
def table(rows, rule):
T = [[1]]
for n in range(1, rows):
prev = T[-1] + [0]
T.append([rule(n, k, prev) for k in range(n + 1)])
return T
S = table(9, lambda n, k, p: (k * p[k] if k < len(p) else 0) + (p[k - 1] if k else 0))
c = table(9, lambda n, k, p: ((n - 1) * p[k] if k < len(p) else 0) + (p[k - 1] if k else 0))
bell = [sum(row) for row in S]
catalan = [comb(2 * n, n) // (n + 1) for n in range(9)]
derange = [round(factorial(n) * sum((-1) ** i / factorial(i) for i in range(n + 1))) for n in range(9)]
def partitions(n, largest=None):
largest = n if largest is None else largest
if n == 0: return 1
return sum(partitions(n - j, j) for j in range(1, min(n, largest) + 1))
print("Bell ", bell)
print("Catalan ", catalan)
print("derangements", derange)
print("partitions ", [partitions(n) for n in range(9)])
print("S(n,k) row 5", S[5], " c(n,k) row 5", c[5])
# graph models: cluster graphs on [n] are counted by Bell numbers
def is_cluster(n, E):
adj = {v: {v} for v in range(n)}
for a, b in E:
adj[a].add(b); adj[b].add(a)
return all(adj[a] == adj[b] for a, b in E) # an edge joins two vertices with equal closed neighbourhoods
for n in range(1, 6):
pairs = list(combinations(range(n), 2))
count = sum(is_cluster(n, [pairs[i] for i in range(len(pairs)) if m >> i & 1]) for m in range(1 << len(pairs)))
print(f"cluster graphs on [{n}]: {count} = B_{n} = {bell[n]}")
Exercise 1.9.1 Pure
Prove that a graph is a cluster graph if and only if it has no induced path \(P_3\), and deduce that \(B_n\) counts the \(P_3\)-free graphs on \([n]\).
Exercise 1.9.2 Pure
Prove that \(S(n,2)=2^{n-1}-1\) and \(S(n,n-1)=\binom n2\), and give a graph interpretation of each.
\(S(n,n-1)\): the cluster graphs with \(n-1\) components have exactly one edge.
Exercise 1.9.3 Pure Math Olympiad
Prove the recurrence \(D_n=(n-1)(D_{n-1}+D_{n-2})\) for derangements.
Look at the element \(\sigma(n)=i\), and ask whether \(\sigma(i)=n\).
Exercise 1.9.4 Pure
Prove that a convex \((n+2)\)-gon has \(\mathrm{Cat}_n\) triangulations.
The side between vertices \(1\) and \(n+2\) lies in exactly one triangle; its third vertex splits the polygon in two.
Exercise 1.9.5 Code
Compute \(p(100)\) with the program of this section after making it fast enough (use memoisation).
Exercise 1.9.6 Pure
Show that the number of surjections from \([n]\) onto \([k]\) is \(k!\,S(n,k)\), and deduce \(\sum_k k!\,S(n,k)\binom xk=x^n\) for every positive integer \(x\).
Exercise 1.9.7 Research Project
A small research project: Stirling-like triangles from graphs.
Show that \(\binom nk\), \(S(n,k)\), \(c(n,k)\) and the Lah numbers \(L(n,k)=\binom{n-1}{k-1}\frac{n!}{k!}\) all satisfy recurrences of the form \(a(n,k)=f(n,k)\,a(n-1,k-1)+g(n,k)\,a(n-1,k)\), and find \(f\) and \(g\) in each case.
Let \(a(n,k)\) be the number of graphs on \([n]\) whose components are all paths, with exactly \(k\) components. Compute a table for \(n\leqslant6\) and decide whether it satisfies such a recurrence.
Find other families of graphs, counted by number of components, that do.
Open-ended: characterise the pairs \((f,g)\) for which \(a(n,k)\) counts a natural family of labeled graphs by number of components.
For (a), Lah numbers count partitions of \([n]\) into \(k\) non-empty ordered lists: \(f=1\), \(g=n-1+k\).
For (b), a component that is a path on \(j\geqslant2\) vertices can be labeled in \(j!/2\) ways.
We end the chapter by stepping back. Suppose we want the number \(\mathcal C_n\) of connected graphs on \([n]\). What would count as an answer? The question is less innocent than it looks, because \(\mathcal C_n\) has no formula of the kind \(n^{n-2}\), yet we can say a great deal about it. Five kinds of answers are possible, and they are the five chapters that follow.
H. S. Wilf, What is an answer?, American Mathematical Monthly 89 (1982), 289–292. The paper is four pages long and still worth reading.
Wilf’s criterion is simple. Listing all objects takes time at least proportional to their number, which usually grows exponentially. A formula is a good answer if it computes the number much faster than listing, ideally in time polynomial in \(n\). By this criterion a sum with exponentially many terms is not much of an answer, however explicit it looks, while a simple recurrence may be an excellent one.
1. An explicit sum (Chapter 2). Inclusion–exclusion over the partitions of \([n]\) gives \[\mathcal C_n=\sum_{\pi}(-1)^{|\pi|-1}(|\pi|-1)!\;2^{\sum_{B\in\pi}\binom{|B|}2},\] where \(\pi\) runs over all partitions of \([n]\) and \(|\pi|\) is the number of blocks. The formula is explicit, but it has \(B_n\) terms, so by Wilf’s criterion it is a poor answer.
2. A recurrence (Chapter 4). Choose the component of vertex \(1\); if it has \(k\) vertices, it is a connected graph on \(1\) and \(k-1\) other vertices, and the rest is any graph. So \[2^{\binom n2}=\sum_{k=1}^{n}\binom{n-1}{k-1}\,\mathcal C_k\,2^{\binom{n-k}2},\] which computes \(\mathcal C_n\) from \(\mathcal C_1,\ldots,\mathcal C_{n-1}\) with \(O(n^2)\) arithmetic operations. This is an excellent answer.
3. A generating function (Chapter 5). With \(G(x)=\sum_{n\geqslant0}2^{\binom n2}\frac{x^n}{n!}\) and \(C(x)=\sum_{n\geqslant1}\mathcal C_n\frac{x^n}{n!}\), \[C(x)=\log G(x).\] The power series \(G(x)\) converges nowhere except at \(0\), yet the identity holds as an identity of formal power series, and the recurrence above is what one gets by differentiating it.
4. An estimate (Chapter 6). Almost all graphs are connected: \(\mathcal C_n/2^{\binom n2}\to1\). More precisely, the proportion of disconnected graphs is asymptotic to \(n\,2^{1-n}\), the proportion of graphs with an isolated vertex.
5. A bound (Chapter 7). A connected graph on \(n\) vertices has at least \(n-1\) edges, with equality exactly for trees; and every graph with more than \(\binom{n-1}2\) edges is connected (Exercise 1.2.2). Both bounds are sharp.
| \(n\) | \(\mathcal C_n\) | \(2^{\binom n2}\) | proportion disconnected | \(n\,2^{1-n}\) |
|---|---|---|---|---|
| 1 | 1 | 1 | 0 | 1 |
| 2 | 1 | 2 | 0.5 | 1 |
| 3 | 4 | 8 | 0.5 | 0.75 |
| 4 | 38 | 64 | 0.406 | 0.5 |
| 5 | 728 | 1024 | 0.289 | 0.3125 |
| 6 | 26704 | 32768 | 0.185 | 0.1875 |
| 7 | 1866256 | 2097152 | 0.110 | 0.1094 |
| 8 | 251548592 | 268435456 | 0.0629 | 0.0625 |
| 9 | 66296291072 | 68719476736 | 0.0353 | 0.0352 |
| 10 | 34496488594816 | 35184372088832 | 0.0196 | 0.0195 |
from math import comb, factorial, log
N = 10
# 2. the recurrence
C = [0, 1]
for n in range(2, N + 1):
C.append(2 ** comb(n, 2) - sum(comb(n - 1, k - 1) * C[k] * 2 ** comb(n - k, 2) for k in range(1, n)))
# 1. the explicit sum over set partitions (slow on purpose)
def set_partitions(s):
if not s:
yield []; return
first, rest = s[0], s[1:]
for p in set_partitions(rest):
yield [[first]] + p
for i in range(len(p)):
yield p[:i] + [[first] + p[i]] + p[i + 1:]
def explicit(n):
return sum((-1) ** (len(p) - 1) * factorial(len(p) - 1) * 2 ** sum(comb(len(b), 2) for b in p)
for p in set_partitions(list(range(n))))
# 3. coefficients of log G(x) as formal power series, with exact fractions
from fractions import Fraction
g = [Fraction(2 ** comb(n, 2), factorial(n)) for n in range(N + 1)]
c = [Fraction(0)] * (N + 1) # log G: n c_n = n g_n - sum_{k<n} k c_k g_{n-k}
for n in range(1, N + 1):
c[n] = (n * g[n] - sum(k * c[k] * g[n - k] for k in range(1, n))) / n
from_log = [int(c[n] * factorial(n)) for n in range(N + 1)]
for n in range(1, N + 1):
ex = explicit(n) if n <= 8 else "(skipped)"
print(f"n={n:2} recurrence {C[n]:>15} log G {from_log[n]:>15} explicit {ex}"
f" disconnected {1 - C[n] / 2 ** comb(n, 2):.4f} n*2^(1-n) {n * 2 ** (1 - n):.4f}")
The program computes \(\mathcal C_n\) in three of the five ways, by the recurrence, by the logarithm of a power series and by the explicit sum, and compares the proportion of disconnected graphs with \(n2^{1-n}\). The explicit sum is stopped at \(n=8\), where it already adds \(4140\) terms; the recurrence would reach \(n=1000\) in seconds.
One number, many proofs
The number \(\mathcal C_n\) of connected labeled graphs follows us through the book. Chapter 2 derives the explicit sum by Möbius inversion on the partition lattice; Chapter 4 proves the recurrence and its version for graphs with \(k\) components, which goes back to the 2014 Persian edition of this book; Chapter 5 obtains \(C(x)=\log G(x)\) from the exponential formula; Chapter 6 proves that almost all graphs are connected; Chapter 7 studies the extremal questions. The other running problem, the number of trees, follows the same path.
Exercise 1.10.1 Pure
Derive the recurrence of answer 2 carefully, and use it to compute \(\mathcal C_4\) by hand.
Exercise 1.10.2 Code
Compute \(\mathcal C_{10}\) with the recurrence.
Exercise 1.10.3 Pure
Prove that the proportion of graphs on \([n]\) with an isolated vertex is at most \(n\,2^{1-n}\) and at least \(n\,2^{1-n}-\binom n2 2^{3-2n}\).
Use the union bound over vertices, then subtract the pairs of isolated vertices (inclusion–exclusion, Chapter 2).
Exercise 1.10.4 Math Olympiad
Prove that the proportion of disconnected graphs on \([n]\) is at most \(\sum_{k=1}^{\lfloor n/2\rfloor}\binom nk2^{-k(n-k)}\), and deduce that almost all graphs are connected.
A disconnected graph has a set \(S\) with \(|S|\leqslant n/2\) and no edges between \(S\) and its complement.
Exercise 1.10.5 Computer Science
By Wilf’s criterion, compare the three methods of the program. Estimate the number of arithmetic operations of each as a function of \(n\).
Exercise 1.10.6 Research Project Code
A small research project: graphs with \(k\) components.
Let \(\mathcal D_n(k)\) be the number of graphs on \([n]\) with exactly \(k\) components.
Compute \(\mathcal D_n(k)\) for \(n\leqslant8\) from the numbers \(\mathcal C_j\), using the formula of the 2014 Persian edition: choose the vertex sets of the components and a connected graph on each.
Show that \(\sum_n\mathcal D_n(k)\frac{x^n}{n!}=\frac{C(x)^k}{k!}\).
For fixed \(k\), find the asymptotic proportion of graphs on \([n]\) with exactly \(k\) components as \(n\to\infty\).
Open-ended: in a random graph on \([n]\), what is the expected number of components? Compute it for \(n\leqslant12\) and compare with \(1+n2^{1-n}\).
For (c): almost all graphs with \(k\) components consist of one giant component and \(k-1\) isolated vertices.
This chapter collects the counting problems in graph theory that have a closed answer obtainable by elementary means: the sum and product rules, bijections, double counting, inclusion–exclusion and Möbius inversion. We start with the simplest family of all, the graphs on a fixed vertex set.
We already know from Proposition 1.1.8 that there are \(2^{\binom n2}\) graphs on \([n]\) and \(\binom{\binom n2}m\) of them with \(m\) edges. A small change in the question often keeps the answer simple, provided we find the right bijection. Here is the first example.
Theorem 2.1.1. The number of graphs on \([n]\) in which every vertex has even degree is \(2^{\binom{n-1}2}\).
Proof. Let \(H\) be any graph on \([n-1]\). By Corollary 1.1.6, \(H\) has an even number of odd vertices. Join the new vertex \(n\) to exactly these odd vertices. Every old vertex now has even degree, and \(n\) has even degree too. Conversely, deleting \(n\) from a graph on \([n]\) with all degrees even recovers a graph on \([n-1]\), and the odd vertices of that graph are exactly the neighbours of \(n\). The two maps are inverse to each other, so the even graphs on \([n]\) are in bijection with all graphs on \([n-1]\).
Corollary 2.1.2. If \(n\) is even, there are \(2^{\binom{n-1}2}\) graphs on \([n]\) in which every vertex has odd degree. If \(n\) is odd there are none.
Proof. For odd \(n\) the handshake lemma forbids an odd number of odd vertices. For even \(n\), complementation changes each degree \(d\) into \(n-1-d\), which has the opposite parity because \(n-1\) is odd; so the complement is a bijection between the graphs with all degrees even and those with all degrees odd.
Even graphs are the graphs whose every component has an Eulerian circuit (Section 2.8). They are also the elements of the cycle space of \(K_n\), a vector space over the field with two elements, and Theorem 2.1.1 says that this space has dimension \(\binom{n-1}2\). A count that is a power of \(2\) often hides a vector space.
Proposition 2.1.3. The number of graphs on \([n]\) in which vertex \(1\) has degree \(k\) is \(\binom{n-1}k2^{\binom{n-1}2}\).
Proof. Choose the \(k\) neighbours of \(1\) and, independently, any graph on the other \(n-1\) vertices.
Fixing the degree of every vertex is much harder: there is no simple formula for the number of graphs with a given degree sequence, and Chapter 6 gives an asymptotic answer. Fixing a bipartition, on the other hand, is easy.
Proposition 2.1.4. Let \(V_1\cup V_2\) be a partition of \([n]\) with \(|V_1|=k\). There are \(2^{k(n-k)}\) bipartite graphs with this bipartition, that is, graphs with no edge inside \(V_1\) or inside \(V_2\). Consequently the number of bicoloured graphs on \([n]\), pairs consisting of a graph and a proper colouring of its vertices with the colours red and blue, is \[b_n=\sum_{k=0}^n\binom nk2^{k(n-k)}.\]
The sequence \(b_n\) begins \(2, 6, 26, 162, 1442\). It is not the number of bipartite graphs, because a bipartite graph with \(c\) components has \(2^c\) proper red–blue colourings. Separating these two counts needs the exponential formula of Chapter 5; it is a good example of a problem whose elementary answer is one step away from the answer we want.
Proposition 2.1.5. On the vertex set \([n]\) there are
Proof. Each of the \(\binom n2\) pairs \(\{u,v\}\) independently carries no arc, the arc \(uv\), the arc \(vu\), or both: four choices for digraphs, three for oriented graphs, two for tournaments. An orientation chooses one of two directions for each edge.
Definition 2.1.6. A tournament is transitive if \(u\to v\) and \(v\to w\) imply \(u\to w\).
Proposition 2.1.7. A tournament is transitive if and only if it has no directed triangle, and there are exactly \(n!\) transitive tournaments on \([n]\).
Proof. A directed triangle \(u\to v\to w\to u\) violates transitivity. Conversely, in a tournament without directed triangles, if \(u\to v\to w\) then \(w\to u\) would close a directed triangle, so \(u\to w\). A transitive tournament is the same as a strict linear order of \([n]\) (put \(u\) before \(v\) when \(u\to v\)), and there are \(n!\) linear orders.
from itertools import combinations
from math import comb
def graphs(n):
pairs = list(combinations(range(n), 2))
for mask in range(1 << len(pairs)):
yield [pairs[i] for i in range(len(pairs)) if mask >> i & 1]
def degrees(n, E):
d = [0] * n
for a, b in E:
d[a] += 1; d[b] += 1
return d
for n in range(1, 7):
even = odd = 0
for E in graphs(n):
d = degrees(n, E)
even += all(x % 2 == 0 for x in d)
odd += all(x % 2 == 1 for x in d)
bic = sum(comb(n, k) * 2 ** (k * (n - k)) for k in range(n + 1))
print(f"n={n}: all even {even:5} = 2^C(n-1,2) = {2 ** comb(n - 1, 2):5}; all odd {odd:5}; bicoloured {bic}")
Exercise 2.1.1 Pure
How many graphs on \([n]\) have vertices \(1\) and \(2\) adjacent with no common neighbour?
Each of the vertices \(3,\ldots,n\) may be joined to \(1\), to \(2\), or to neither, but not to both.
Exercise 2.1.2 Pure
Give a second proof of Theorem 2.1.1: show that the map sending a graph \(G\) on \([n]\) to the set of its odd vertices is \(2^{\binom{n-1}2}\)-to-one onto the even subsets of \([n]\).
Adding a path between two vertices changes the parity of exactly those two degrees.
Exercise 2.1.3 Pure Math Olympiad
Prove that every tournament has a vertex from which every other vertex can be reached by a directed path of length at most \(2\) (a king).
Take a vertex of maximum out-degree.
Exercise 2.1.4 Pure
How many oriented graphs are there on \([n]\)?
Exercise 2.1.5 Code
Confirm Corollary 2.1.2 for \(n\leqslant6\) with the program of this section, and extend the program to count graphs in which every degree is divisible by \(3\). Look for your numbers in the OEIS.
Exercise 2.1.6 Pure
Let \(T\) be a tournament on \([n]\) with out-degrees \(d^+(1),\ldots,d^+(n)\). Prove that the number of directed triangles of \(T\) is \(\binom n3-\sum_v\binom{d^+(v)}2\).
A triple of vertices that is not a directed triangle has exactly one vertex beating the other two.
Exercise 2.1.7 Research Project Code
A small research project: degrees modulo \(q\).
For \(q=2\), Theorem 2.1.1 counts the graphs on \([n]\) with all degrees \(\equiv0\pmod q\). Compute the analogous numbers for \(q=3\) and \(n\leqslant7\).
Count the graphs on \([n]\) with all degrees even and an even number of edges. Prove that for \(n\geqslant3\) the answer is \(2^{\binom{n-1}2-1}\).
Use the characters \(x\mapsto e^{2\pi i x/q}\) to write the count of (a) as an average over \(\{0,\ldots,q-1\}^n\) of a product over edges. Simplify it for \(q=2\) to recover Theorem 2.1.1.
Open-ended: what can be said about \(q=3\)? Is there a closed formula, a recurrence, or only an asymptotic estimate?
For (c): the indicator of \(d\equiv0\pmod q\) is \(\frac1q\sum_{a=0}^{q-1}\omega^{ad}\) with \(\omega=e^{2\pi i/q}\), and \(d(v)=\sum_{u}x_{uv}\).
Double counting means counting one set in two different ways. Applied to graphs, it usually counts small configurations, such as edges at a vertex, paths of length two or triangles, once by their vertices and once by their edges. The resulting identities are among the most useful tools of the subject.
Proposition 2.2.1. For every graph \(G\), \[\sum_{v}\deg(v)^2=\sum_{uv\in E}\big(\deg(u)+\deg(v)\big),\] and the number of paths of length \(2\) in \(G\) (cherries) is \(\sum_v\binom{\deg(v)}2\).
Proof. Count pairs \((e,f)\) of edges, \(e\) and \(f\) possibly equal, that share an end, together with that end: for a vertex \(v\) there are \(\deg(v)^2\) such pairs; for a fixed edge \(e=uv\) there are \(\deg(u)+\deg(v)\) choices of \((f,\text{shared end})\). A cherry is a vertex together with two of its edges.
A. W. Goodman
American mathematician. In 1959 he proved the identity below and deduced the minimum number of monochromatic triangles in a two-colouring of \(K_n\), the first Ramsey multiplicity result.
Theorem 2.2.2 (Goodman). Let \(G\) be a graph on \(n\) vertices and let \(t(G)\) be its number of triangles. Then \[t(G)+t(\overline G)=\binom n3-\frac12\sum_{v}\deg(v)\,\big(n-1-\deg(v)\big).\]
Proof. Colour the edges of \(K_n\) red if they belong to \(G\) and blue otherwise. A triangle of \(K_n\) is monochromatic if its three edges have the same colour; otherwise it has two edges of one colour and one of the other, and exactly two of its three corners see one red and one blue edge. Call a vertex together with one red and one blue edge at it a bicoloured corner. Counting bicoloured corners by vertices gives \(\sum_v\deg(v)(n-1-\deg(v))\); counting them by triangles gives \(2\) for each non-monochromatic triangle and \(0\) for each monochromatic one. So the number of non-monochromatic triangles is \(\frac12\sum_v\deg(v)(n-1-\deg(v))\).
Corollary 2.2.3. In every two-colouring of the edges of \(K_n\) there are at least \(\frac{n(n-1)(n-5)}{24}\) monochromatic triangles. In particular every two-colouring of \(K_6\) has at least two monochromatic triangles.
Proof. Each term \(\deg(v)(n-1-\deg(v))\) is at most \(\left(\frac{n-1}2\right)^2\), so Theorem 2.2.2 gives at least \(\binom n3-\frac{n(n-1)^2}8=\frac{n(n-1)(n-5)}{24}\). For \(n=6\) this is \(\frac54\), so there are at least \(2\).
The statement for \(K_6\) is a strengthening of the first case of Ramsey’s theorem, \(R(3,3)=6\), which Chapter 7 treats in general. Notice the mechanism: an identity produced by double counting, followed by a single inequality. This pattern turns exact counts into extremal results again and again.
Research thread · Ramsey multiplicity of \(K_4\)
Corollary 2.2.3 shows that a random colouring, with about \(\frac14\binom n3\) monochromatic triangles, is asymptotically the best possible for triangles. Erdős conjectured that the same holds for \(K_4\): that every two-colouring of \(K_n\) has at least about \(\frac1{32}\binom n4\) monochromatic copies of \(K_4\). Thomason disproved this in 1989 with explicit colourings that do better, and the exact asymptotic minimum is still unknown as of 2026; computer-assisted flag algebra methods give the best lower bounds. A first step: compute the number of monochromatic \(K_4\) in Thomason-type colourings for small \(n\) by computer and compare with \(\frac1{32}\binom n4\).
Reading: A. Thomason, A disproof of a conjecture of Erdős in Ramsey theory, J. London Math. Soc. 39 (1989), 246–255.
The following identity is the main theorem on connected graphs in the 2014 Persian edition of this book. It determines the number \(\mathcal C_n\) of connected graphs on \([n]\) from the numbers \(2^{\binom n2}\), and it is a model of a double-counting argument with a carefully chosen marking.
Theorem 2.2.4. For every \(n\geqslant1\), \[n\,2^{\binom n2}=\sum_{k=1}^{n}k\binom nk\,\mathcal C_k\,2^{\binom{n-k}2}.\]
Proof. Count the graphs on \([n]\) with one marked vertex. Directly, there are \(n\,2^{\binom n2}\) of them. Alternatively, build such a graph from the component \(C\) of the marked vertex: if \(C\) has \(k\) vertices, choose them in \(\binom nk\) ways, mark one of them in \(k\) ways, make them a connected graph in \(\mathcal C_k\) ways, and put any graph on the remaining \(n-k\) vertices in \(2^{\binom{n-k}2}\) ways. Each marked graph is built exactly once, because the mark tells us which component is \(C\); without the mark, a graph with \(\ell\) components would be counted \(\ell\) times.
Example 2.2.5. With \(\mathcal C_1=\mathcal C_2=1\), \(\mathcal C_3=4\), \(\mathcal C_4=38\), the identity for \(n=5\) reads \[5\cdot1024=5\cdot64\cdot1+2\cdot10\cdot8\cdot1+3\cdot10\cdot2\cdot4+4\cdot5\cdot1\cdot38+5\,\mathcal C_5,\] that is \(5120=320+160+240+760+5\mathcal C_5\), so \(\mathcal C_5=728\).
from itertools import combinations
from math import comb
import random
def triangles(n, E):
E = {frozenset(e) for e in E}
return sum(1 for a, b, c in combinations(range(n), 3)
if {frozenset((a, b)), frozenset((a, c)), frozenset((b, c))} <= E)
random.seed(7)
n = 10
E = [e for e in combinations(range(n), 2) if random.random() < 0.4]
Ebar = [e for e in combinations(range(n), 2) if e not in set(E)]
deg = [sum(v in e for e in E) for v in range(n)]
print("t(G) + t(complement) =", triangles(n, E) + triangles(n, Ebar))
print("Goodman's formula =", comb(n, 3) - sum(d * (n - 1 - d) for d in deg) // 2)
# connected graphs from the identity of the 2014 edition
C = {}
for m in range(1, 11):
rest = sum(k * comb(m, k) * C[k] * 2 ** comb(m - k, 2) for k in range(1, m))
C[m] = (m * 2 ** comb(m, 2) - rest) // m
print([C[m] for m in range(1, 11)])
Exercise 2.2.1 Pure
How many cherries (paths of length \(2\)) does the Petersen graph have? How many does \(Q_n\) have?
Exercise 2.2.2 Pure Math Olympiad
Let \(G\) have \(n\) vertices and \(m\) edges. Prove that \(G\) has at least \(\frac{m(4m-n^2)}{3n}\) triangles.
The ends of an edge \(uv\) have at least \(\deg(u)+\deg(v)-n\) common neighbours.
Sum over the edges and use \(\sum_v\deg(v)^2\geqslant\frac{(2m)^2}n\).
Exercise 2.2.3 Math Olympiad
Show that when the edges of \(K_7\) are coloured red and blue, there are at least \(4\) monochromatic triangles, and find a colouring with exactly \(4\).
Apply Theorem 2.2.2: each term is at most \(3\cdot3\).
The degrees cannot all be \(3\), since \(7\cdot3\) is odd. Six vertices of red degree \(3\) and one of red degree \(4\) give exactly \(4\); search for such a colouring by computer.
Exercise 2.2.4 Pure
Prove that the number of \(4\)-cycles in a graph is \(\frac12\sum_{\{u,w\}}\binom{|N(u)\cap N(w)|}2\), the sum running over unordered pairs of distinct vertices. How many \(4\)-cycles has \(Q_3\)?
Exercise 2.2.5 Code
Use the program of this section to compute \(\mathcal C_6\) and \(\mathcal C_{10}\) from Theorem 2.2.4.
Exercise 2.2.6 Pure Math Olympiad
(Friendship theorem, Erdős–Rényi–Sós 1966.) In a finite graph every two distinct vertices have exactly one common neighbour. Show by double counting that if the graph is \(k\)-regular then \(n=k^2-k+1\), and then read how the theorem concludes that some vertex is adjacent to all others.
Count the cherries in two ways: by their middle vertex, and by their pair of ends.
Two finite sets have the same size if and only if there is a bijection between them. A bijective proof of an identity \(|A|=|B|\) exhibits such a bijection explicitly. It is often the most illuminating proof, because it explains why the numbers agree rather than only showing that they do. In this section we collect bijections that turn graph problems into problems about words and functions.
Definition 2.3.1. A permutation \(\sigma\) of \([n]\) is an involution if \(\sigma(\sigma(i))=i\) for every \(i\). Write \(I_n\) for the number of involutions of \([n]\), with \(I_0=1\).
Proposition 2.3.2. Involutions of \([n]\) are in bijection with matchings of \(K_n\) (sets of pairwise disjoint edges). Consequently \[I_n=\sum_{k\geqslant0}\frac{n!}{k!\,(n-2k)!\,2^k},\qquad I_n=I_{n-1}+(n-1)I_{n-2}\quad(n\geqslant2).\]
Proof. An involution consists of fixed points and \(2\)-cycles; send it to the matching formed by its \(2\)-cycles. A matching with \(k\) edges is obtained by ordering the \(n\) vertices, pairing the first \(2k\) in consecutive pairs, and forgetting the order of the pairs, the order inside each pair and the order of the remaining \(n-2k\) vertices; this gives the sum. For the recurrence, vertex \(n\) is either unmatched, leaving a matching of \(K_{n-1}\), or matched to one of \(n-1\) vertices, leaving a matching of \(K_{n-2}\).
The numbers \(1, 1, 2, 4, 10, 26, 76, 232\) are sometimes called telephone numbers: they count the ways in which \(n\) subscribers can be connected in pairs for calls, with some subscribers idle.
Definition 2.3.3. The functional digraph of a map \(f:[n]\to[n]\) has vertex set \([n]\) and an arc \(i\to f(i)\) for each \(i\), loops allowed. Every vertex has out-degree exactly \(1\), and every digraph with this property is the functional digraph of exactly one map.
So there are \(n^n\) functional digraphs on \([n]\). Their shape is simple: each component contains exactly one directed cycle, possibly a loop, and the rest of the component consists of trees hanging from the cycle with all arcs pointing towards it. A permutation is a functional digraph whose components are just cycles; this is the graph model of \(c(n,k)\) from Section 1.9.
Proposition 2.3.4. A map \(f\) with \(f\circ f=f\) is called idempotent. The number of idempotent maps \([n]\to[n]\) is \(\sum_{k=1}^n\binom nk k^{n-k}\).
Proof. In the functional digraph of an idempotent map every vertex is either a fixed point or is mapped directly to a fixed point. So the digraph is a union of stars, each with a loop at its centre. Choose the set of \(k\) centres and send each of the other \(n-k\) vertices to one of them.
The values are \(1, 3, 10, 41, 196\) for \(n=1,\ldots,5\). In Section 2.4 a cleverer bijection between functions and trees with two marked vertices, due to André Joyal, gives our third proof of Cayley’s formula.
Proposition 2.3.5. The spanning subgraphs of the path \(P_n\) with exactly \(k\) components are in bijection with the compositions of \(n\) into \(k\) parts. In particular there are \(\binom{n-1}{k-1}\) of them.
Proof. Read the components from left to right and record their numbers of vertices; this gives a composition of \(n\) into \(k\) parts, and every composition arises from exactly one spanning subgraph. Equivalently, choose which \(k-1\) of the \(n-1\) edges of \(P_n\) to delete.
This tiny example shows the typical structure of a bijective proof: a graph-theoretic object (a spanning subgraph), a combinatorial word that encodes it (a composition), and an inverse map that rebuilds the object. The Prüfer code of the next section has exactly this structure, with a much less obvious encoding.
The value of bijective proofs was stressed by many combinatorialists of the twentieth century; R. Stanley’s Enumerative Combinatorics lists dozens of identities for which a combinatorial (bijective) proof is still wanted.
from itertools import permutations, product, combinations
def involutions(n):
return sum(all(p[p[i]] == i for i in range(n)) for p in permutations(range(n)))
def matchings(n):
# matchings of K_n by the recurrence of vertex n
I = [1, 1]
for k in range(2, n + 1):
I.append(I[-1] + (k - 1) * I[-2])
return I[n]
def idempotents(n):
return sum(all(f[f[i]] == f[i] for i in range(n)) for f in product(range(n), repeat=n))
for n in range(1, 8):
line = f"n={n}: involutions {involutions(n):4} matchings of K_n {matchings(n):4}"
if n <= 5:
line += f" idempotent maps {idempotents(n)}"
print(line)
Exercise 2.3.1 Pure
Compute \(I_6\) from the recurrence of Proposition 2.3.2.
Exercise 2.3.2 Pure
How many idempotent maps \([5]\to[5]\) are there?
Exercise 2.3.3 Pure
How many spanning subgraphs of the cycle \(C_n\) have exactly \(k\) components? Treat \(k=1\) separately.
Deleting \(j\geqslant1\) edges of a cycle leaves \(j\) components.
Exercise 2.3.4 Pure
Prove that the number of maps \(f:[n]\to[n]\) without fixed points is \((n-1)^n\), and that the number of permutations of \([n]\) in which no \(i\) is immediately followed by \(i+1\) is \(D_n+D_{n-1}\).
For the second part, use inclusion–exclusion (Section 2.6), or find a bijection with derangements of \([n]\) and of \([n-1]\).
Exercise 2.3.5 Algorithm Informatics Olympiad
Write a recursive procedure that lists all matchings of \(K_n\), each exactly once, in time proportional to their number. Use it to list the \(26\) matchings of \(K_5\).
Decide the fate of the smallest unprocessed vertex: unmatched, or matched to a larger vertex.
Exercise 2.3.6 Code
Count the connected functional digraphs on \([n]\) for \(n\leqslant5\) by brute force, and compare with \(\sum_{k=1}^{n}\frac{(n-1)!}{(n-k)!}\,n^{\,n-k}\). (Section 2.5 proves the formula.)
How many ways are there to connect \(n\) cities by roads so that every city can reach every other one and not a single road is wasted? Suppose the cities are named \(1,2,\ldots,n\) and a road joins two cities directly. “Not wasting a road” means that removing any road cuts some city off, that is, every edge is a bridge. By Lemma 1.2.11 and Theorem 1.6.3 these are exactly the trees on \([n]\).
The question is older than our cities. In the 1870s Cayley was counting the possible molecules of the alkanes \(C_nH_{2n+2}\), whose carbon atoms form a tree, and his method went through counting trees with named vertices first. The answer he found is one of the most quotable formulas in combinatorics.
Definition 2.4.1. A labeled tree on \([n]\) is a tree with vertex set \([n]\). We write \(t_n\) for the number of labeled trees on \([n]\); equivalently, \(t_n\) is the number of spanning trees of \(K_n\).
Two labeled trees are equal only when they have the same edges, so the path \(1-2-3\) and the path \(2-1-3\) are different labeled trees although they are isomorphic. This is exactly the distinction of Section 1.3.
For \(n=1,2\) there is one tree, and for \(n=3\) a tree is a path decided by its middle vertex, so \(t_3=3\). For \(n=4\) there are two shapes, the path \(P_4\) and the star \(K_{1,3}\); by Example 1.3.4 there are \(4!/2=12\) labeled paths and \(4\) labeled stars, so \(t_4=16\).
Example 2.4.2. The sixteen labeled trees on \([4]\): twelve paths, drawn in ink, and four stars, drawn in green.
Figure 2.4.3. The sixteen labeled trees on \([4]\).
For \(n=5\) there are three shapes: the path \(P_5\) with \(5!/2=60\) labeled copies; the star \(K_{1,4}\) with \(5\); and the fork, a vertex of degree \(3\) with one branch extended by an edge, whose automorphism group has order \(2\), giving \(5!/2=60\) copies. So \(t_5=60+5+60=125\).
The sequence \(1, 1, 3, 16, 125, 1296, 16807,\ldots\) is A000272 in the On-Line Encyclopedia of Integer Sequences.
Anyone who has stared at \(16=4^2\) and \(125=5^3\) will make the same guess, and \(3=3^1\) agrees: \(t_n=n^{n-2}\).
Remark 2.4.4. A guess that fits five numbers is still only a guess. The only safe way forward is a proof, and in this section we give three.
C. W. Borchardt obtained the formula in 1860 using determinants, and Cayley stated it in 1889 in a three-page note, A theorem on trees, crediting Borchardt. Some authors call it the Borchardt–Cayley formula.
Theorem 2.4.5 (Cayley’s formula). For every \(n\geqslant1\) the number of labeled trees on \([n]\) is \[t_n=n^{\,n-2}.\]
The right-hand side counts the words of length \(n-2\) over the alphabet \([n]\). So the theorem invites a bijection between trees and words, and our first proof builds one.
Heinz Prüfer (1896–1934)
German mathematician. He published this proof in 1918 at the age of 22; his name is better known in algebra, through Prüfer groups and Prüfer domains.
Throughout, \(T\) is a labeled tree on \([n]\) with \(n\geqslant3\). By Lemma 1.6.2 it has at least two leaves, and deleting a leaf from a tree leaves a tree.
Definition 2.4.6. The Prüfer sequence \(P(T)=(a_1,\ldots,a_{n-2})\) is produced by repeating \(n-2\) times: let \(\ell\) be the smallest leaf of the current tree, write down its unique neighbour, and delete \(\ell\).
Example 2.4.7. Take the tree on \([7]\) with edges \(16,\ 25,\ 35,\ 46,\ 57,\ 67\). The successive smallest leaves are \(1,2,3,4,5\) and their neighbours are \(6,5,5,6,7\); so \(P(T)=(6,5,5,6,7)\), and the edge \(67\) remains at the end.
Figure 2.4.8. The tree of Example 2.4.7.
In the example the vertices \(5\) and \(6\) have degree \(3\) and appear twice, \(7\) has degree \(2\) and appears once, and the leaves never appear. This is no accident.
Lemma 2.4.9. Every vertex \(v\) appears in \(P(T)\) exactly \(\deg_T(v)-1\) times. In particular the leaves of \(T\) are exactly the labels missing from \(P(T)\).
Proof. In a tree with at least three vertices the neighbour of a leaf is not a leaf. So at each step the recorded vertex survives and loses one edge, while the deleted leaf loses its only edge without being recorded. Follow a fixed vertex \(v\): every edge at \(v\) except one is removed at a step where \(v\) is recorded; the last one is removed when \(v\) itself is deleted as a leaf, or never, if \(v\) is one of the two survivors. Either way \(v\) is recorded \(\deg_T(v)-1\) times.
Lemma 2.4.10. For every word \((a_1,\ldots,a_{n-2})\in[n]^{n-2}\) there is exactly one labeled tree \(T\) on \([n]\) with \(P(T)=(a_1,\ldots,a_{n-2})\).
Proof. Induction on \(n\); for \(n=3\) the tree is the path with middle vertex \(a_1\). Let \(n\geqslant4\). If \(P(T)=(a_1,\ldots,a_{n-2})\), then by Lemma 2.4.9 the first deleted leaf is \(\ell_1=\min\big([n]\setminus\{a_1,\ldots,a_{n-2}\}\big)\), \(T\) contains the edge \(\ell_1a_1\), and \(T-\ell_1\) is a tree on \([n]\setminus\{\ell_1\}\) with Prüfer sequence \((a_2,\ldots,a_{n-2})\). By induction \(T-\ell_1\), and hence \(T\), is unique.
For existence, build by induction the tree \(T'\) on \([n]\setminus\{\ell_1\}\) with sequence \((a_2,\ldots,a_{n-2})\) and attach \(\ell_1\) to \(a_1\). Every label smaller than \(\ell_1\) occurs in the word, so none of them is a leaf of \(T'\) (by Lemma 2.4.9) or of \(T\). Hence \(\ell_1\) is the smallest leaf of \(T\), the procedure writes \(a_1\) first and then continues as on \(T'\).
Proof of Theorem 2.4.5. For \(n=1,2\) both sides equal \(1\). For \(n\geqslant3\), Lemma 2.4.10 says that \(T\mapsto P(T)\) is a bijection from the labeled trees on \([n]\) to \([n]^{n-2}\).
Example 2.4.11. To decode \((6,5,5,6,7)\), repeatedly join the smallest label that is neither used up nor still in the remaining word to the first letter of the word: \(1\)–\(6\), \(2\)–\(5\), \(3\)–\(5\), \(4\)–\(6\), \(5\)–\(7\), and finally the two labels left, \(6\)–\(7\). This is the tree of Example 2.4.7.
from itertools import combinations, product
def prufer(n, edges):
nbr = {v: set() for v in range(1, n + 1)}
for u, v in edges:
nbr[u].add(v); nbr[v].add(u)
word = []
for _ in range(n - 2):
leaf = min(v for v in nbr if len(nbr[v]) == 1)
(p,) = nbr[leaf]
word.append(p)
nbr[p].discard(leaf); del nbr[leaf]
return word
def decode(n, word):
left = {v: word.count(v) for v in range(1, n + 1)}
alive, edges = set(range(1, n + 1)), []
for a in word:
leaf = min(v for v in alive if left[v] == 0)
edges.append((leaf, a)); alive.remove(leaf); left[a] -= 1
edges.append(tuple(sorted(alive)))
return edges
def is_tree(n, edges):
parent = list(range(n + 1))
def find(x):
while parent[x] != x:
parent[x] = parent[parent[x]]; x = parent[x]
return x
for u, v in edges:
ru, rv = find(u), find(v)
if ru == rv:
return False
parent[ru] = rv
return True
print("P(T) =", prufer(7, [(1, 6), (2, 5), (3, 5), (4, 6), (5, 7), (6, 7)]))
for n in range(2, 8):
t = sum(is_tree(n, S) for S in combinations(list(combinations(range(1, n + 1), 2)), n - 1))
ok = all(prufer(n, decode(n, list(w))) == list(w) for w in product(range(1, n + 1), repeat=n - 2))
print(f"n={n}: brute force {t:>6} n^(n-2) = {n ** (n - 2):>6} round trip ok: {ok}")
Jim Pitman (born 1949)
Australian-American probabilist at Berkeley. He found this proof in 1999 while studying how random forests merge; Aigner and Ziegler single it out as their favourite in Proofs from THE BOOK.
Second proof of Theorem 2.4.5. Count triples \((T,r,\sigma)\): a labeled tree \(T\) on \([n]\), a root \(r\), and an ordering \(\sigma\) of its \(n-1\) edges. There are \(t_n\cdot n\cdot(n-1)!\) of them.
Now build them instead. Orient every edge of a rooted tree towards the root. Start with the forest of \(n\) one-vertex trees, each its own root, and add the edges in order. When the forest has \(k\) components, the next edge joins any vertex \(v\) (\(n\) choices) to the root of one of the \(k-1\) components not containing \(v\) (\(k-1\) choices), and that component then hangs below \(v\). This gives \(\prod_{k=2}^n n(k-1)=n^{n-1}(n-1)!\) building sequences, and each triple arises from exactly one of them. Hence \(t_n\,n\,(n-1)!=n^{n-1}(n-1)!\), that is, \(t_n=n^{n-2}\).
André Joyal (born 1943)
Canadian mathematician, founder of the theory of combinatorial species. His 1981 bijection below is one of the first results of that theory.
Third proof of Theorem 2.4.5. A vertebrate is a labeled tree on \([n]\) with two marked vertices, a head \(h\) and a tail \(t\), possibly equal; there are \(n^2t_n\) of them. We show that there are \(n^n\), the number of maps \(f:[n]\to[n]\).
The path from \(t\) to \(h\) is the spine, with vertices \(s_1=t,s_2,\ldots,s_k=h\). Let \(a_1<a_2<\cdots<a_k\) be the same vertices in increasing order, and define \(f(a_i)=s_i\); this permutation of the spine is a union of directed cycles. Every vertex \(v\) off the spine has a unique neighbour on the path from \(v\) to the spine; set \(f(v)\) equal to that neighbour. The functional digraph of \(f\) (Section 2.3) consists of the cycles of the spine permutation with the rest of the tree hanging from them, and from any map \(f\) we recover the vertebrate: the vertices on cycles of \(f\) are the spine, the permutation they carry, written in the order of increasing labels, spells out \(s_1,\ldots,s_k\), and the remaining arcs are the other edges. So \(n^2t_n=n^n\).
One number, many proofs
The number \(n^{n-2}\) returns several times in this book. In Chapter 3 it is the determinant of an \((n-1)\times(n-1)\) matrix (Matrix-Tree Theorem). In Chapter 5 the exponential generating function of rooted labeled trees satisfies \(R(x)=x\,e^{R(x)}\), and Lagrange inversion gives \(n^{n-1}\) rooted trees. In Chapter 6 we ask what a random tree looks like. Counting unlabeled trees, where no simple formula exists, is one of the threads of Chapter 4.
Research thread · The Graceful Tree Conjecture
A graceful labeling of a tree with \(m\) edges uses the labels \(0,1,\ldots,m\) on its vertices so that the \(m\) edge differences are exactly \(1,\ldots,m\). The Ringel–Kotzig conjecture says every tree has one. It has been checked by computer for all trees with at most 35 vertices and is open as of 2026. Paths, stars and caterpillars are graceful. A first step: prove that every tree of diameter at most \(3\) is graceful.
Reading: J. A. Gallian, A Dynamic Survey of Graph Labeling, Electron. J. Combin., Dynamic Survey DS6.
From the authors’ research
D. Yaqubi and M. Mirzavaziri, sparse rulers and graceful labelings (title to be confirmed) · preprint
[Authors: summarise in two or three sentences how the labeling invariant \(L(G)\) generalises sparse rulers and graceful labelings, and add the preprint link.]
Exercise 2.4.1 Pure
Show that the number of labeled trees on \([n]\) in which vertex \(1\) is a leaf is \((n-1)^{n-2}\).
Vertex \(1\) is a leaf exactly when the letter \(1\) is missing from the Prüfer word.
Exercise 2.4.2 Pure Math Olympiad
Show that the number of labeled trees on \([n]\) in which vertex \(1\) has degree \(k\) is \(\binom{n-2}{k-1}(n-1)^{n-k-1}\), and check that these numbers add up to \(n^{n-2}\).
The letter \(1\) occurs exactly \(k-1\) times in the Prüfer word.
Exercise 2.4.3 Algorithm
The code above finds the smallest leaf by scanning all vertices, which costs \(O(n^2)\) in total. Show that encoding and decoding can be done in \(O(n\log n)\) time with a priority queue, and then in \(O(n)\) time.
For linear time, keep a pointer that only moves forward, and notice when the vertex just written down becomes a leaf smaller than the pointer.
Exercise 2.4.4 Code Informatics Olympiad
Write a program that generates a uniformly random labeled tree on \(10^6\) vertices in under a second, and report its maximum degree.
A uniformly random word in \([n]^{n-2}\) decodes to a uniformly random tree, because the code is a bijection.
Exercise 2.4.5 Pure
Choose a labeled tree on \([n]\) uniformly at random. Find the probability \(p_n\) that vertex \(1\) is a leaf, and \(\lim_{n\to\infty}p_n\).
Use Exercise 2.4.1 and the limit of \((1-1/n)^n\).
Exercise 2.4.6 Pure
Fill in the details of the third proof: check that the map from vertebrates to functions is well defined and that the inverse map described really produces a tree.
The Prüfer code does more than count trees. Because it records the degree of every vertex (Lemma 2.4.9), it counts trees with prescribed degrees, with a prescribed number of leaves, and, with one more idea, forests with prescribed roots.
Theorem 2.5.1. Let \(d_1,\ldots,d_n\geqslant1\) with \(d_1+\cdots+d_n=2n-2\). The number of labeled trees on \([n]\) in which vertex \(i\) has degree \(d_i\) for every \(i\) is the multinomial coefficient \[\binom{n-2}{d_1-1,\,\ldots,\,d_n-1}=\frac{(n-2)!}{(d_1-1)!\cdots(d_n-1)!}.\]
Proof. By Lemma 2.4.9 and Lemma 2.4.10, these trees correspond to the words of length \(n-2\) in which the letter \(i\) occurs exactly \(d_i-1\) times, and Proposition 1.8.3 counts these words.
Corollary 2.5.2. Summing Theorem 2.5.1 over all degree sequences gives \(\sum\binom{n-2}{d_1-1,\ldots,d_n-1}=(1+1+\cdots+1)^{n-2}=n^{n-2}\) by the multinomial theorem.
Example 2.5.3. The trees on \([6]\) with degrees \((3,1,1,1,2,2)\) number \(\frac{4!}{2!\,0!\,0!\,0!\,1!\,1!}=12\).
Theorem 2.5.4. For \(2\leqslant k\leqslant n-1\), the number of labeled trees on \([n]\) with exactly \(k\) leaves is \[\frac{n!}{k!}\,S(n-2,\,n-k).\]
Proof. A tree has exactly \(k\) leaves when its Prüfer word uses exactly \(n-k\) different letters. Choose these letters in \(\binom n{n-k}\) ways; the words of length \(n-2\) that use each of them are the surjections from the \(n-2\) positions onto them, and there are \((n-k)!\,S(n-2,n-k)\) of these. Now \(\binom n{n-k}(n-k)!=\frac{n!}{k!}\).
Theorem 2.5.5. Let \(1\leqslant k\leqslant n\). The number of forests on \([n]\) with exactly \(k\) trees, in which the vertices \(1,2,\ldots,k\) lie in different trees, is \[k\,n^{\,n-k-1}.\]
Proof. Add a new vertex \(0\) and join it to \(1,\ldots,k\). This is a bijection from the forests in question to the trees on \(\{0,1,\ldots,n\}\) in which the neighbours of \(0\) are exactly \(1,\ldots,k\). By Exercise 2.4.2 (with \(n+1\) vertices) there are \(\binom{n-1}{k-1}n^{n-k}\) trees on \(\{0,\ldots,n\}\) in which \(0\) has degree \(k\). By symmetry, each of the \(\binom nk\) possible neighbourhoods of \(0\) occurs equally often, so the number we want is \(\binom{n-1}{k-1}n^{n-k}\big/\binom nk=\frac kn\,n^{n-k}\).
Corollary 2.5.6. The number of rooted forests on \([n]\), forests in which every tree has one marked root, is \((n+1)^{n-1}\).
Proof. Join a new vertex \(0\) to all the roots. This is a bijection between rooted forests on \([n]\) and labeled trees on \(\{0,1,\ldots,n\}\), which number \((n+1)^{n-1}\) by Cayley’s formula.
Corollary 2.5.7. The number of connected functional digraphs on \([n]\) is \(\sum_{k=1}^n\frac{(n-1)!}{(n-k)!}\,n^{\,n-k}\).
Proof. A connected functional digraph consists of one directed cycle on some \(k\) vertices and a forest rooted at these \(k\) vertices, with arcs pointing to the roots. There are \(\binom nk(k-1)!\) directed cycles on a \(k\)-set and, by Theorem 2.5.5, \(k\,n^{n-k-1}\) forests rooted at it. The product is \(\frac{n!}{(n-k)!}\,n^{n-k-1}=\frac{(n-1)!}{(n-k)!}\,n^{n-k}\).
The complete graph is the most symmetric host for spanning trees. The next most symmetric hosts are the complete bipartite and multipartite graphs, and for them the answer is again a product of powers.
Theorem 2.5.8. The number of spanning trees of \(K_{m,n}\) is \(m^{\,n-1}n^{\,m-1}\). More generally, the complete multipartite graph \(K_{n_1,\ldots,n_r}\) with \(n=n_1+\cdots+n_r\) vertices has \[n^{\,r-2}\prod_{i=1}^r(n-n_i)^{\,n_i-1}\] spanning trees.
The bipartite case was found by H. I. Scoins in 1962 and the multipartite case by T. L. Austin in 1960. For \(r=n\) and all \(n_i=1\) the formula is Cayley’s. We prove it in Chapter 3 with the Matrix-Tree Theorem; finding a Prüfer-type proof is the research project of this section.
from itertools import combinations, product
from math import comb, factorial
from functools import lru_cache
def is_tree(n, E):
parent = list(range(n))
def find(x):
while parent[x] != x:
x = parent[x]
return x
for a, b in E:
ra, rb = find(a), find(b)
if ra == rb:
return False
parent[ra] = rb
return True
def spanning_trees(n, E):
return [S for S in combinations(E, n - 1) if is_tree(n, S)]
@lru_cache(None)
def S2(m, j):
if m == j: return 1
if j == 0 or j > m: return 0
return j * S2(m - 1, j) + S2(m - 1, j - 1)
n = 6
T = spanning_trees(n, list(combinations(range(n), 2)))
leaves = [sum(sum(v in e for e in t) == 1 for v in range(n)) for t in T]
for k in range(2, n):
print(f"trees on [6] with {k} leaves: {leaves.count(k):4} formula {factorial(n) // factorial(k) * S2(n - 2, n - k)}")
def multipartite(parts):
V, E, start = [], [], 0
blocks = []
for p in parts:
blocks.append(range(start, start + p)); start += p
for i, j in combinations(range(len(parts)), 2):
E += list(product(blocks[i], blocks[j]))
return start, E
for parts in [(2, 3), (3, 3), (1, 2, 3), (2, 2, 2)]:
n, E = multipartite(parts)
formula = n ** (len(parts) - 2)
for p in parts:
formula *= (n - p) ** (p - 1)
print(parts, "brute force", len(spanning_trees(n, E)), " formula", formula)
Exercise 2.5.1 Pure
How many labeled trees on \([7]\) have exactly \(3\) leaves?
Exercise 2.5.2 Pure
How many forests on \([5]\) have exactly two trees, with vertices \(1\) and \(2\) in different trees?
Exercise 2.5.3 Pure
How many rooted forests are there on \([4]\)?
Exercise 2.5.4 Code
Count all forests on \([n]\) (unrooted, any number of trees) for \(n\leqslant5\) by brute force. Then express the count as a sum over the sizes of the trees using Cayley’s formula, and check your formula against the brute force.
Exercise 2.5.5 Pure Math Olympiad
Prove that the number of labeled trees on \([n]\) in which every vertex has degree \(1\) or \(3\) is \(0\) unless \(n\) is even, and find it for \(n=6\).
Use Theorem 2.5.1: the vertices of degree \(3\) appear twice each in the word.
Exercise 2.5.6 Research Project Code
A small research project: spanning trees of complete multipartite graphs.
Compute \(\tau(K_{m,n})\) for \(1\leqslant m,n\leqslant4\) by brute force and confirm Theorem 2.5.8.
A spanning tree of \(K_{m,n}\) has \(m+n-1\) edges. Design a Prüfer-type word, with letters from the two sides kept apart, that proves \(\tau(K_{m,n})=m^{n-1}n^{m-1}\) bijectively.
Extend your code to complete tripartite graphs.
Open-ended: for which other families of graphs can you find codes of this kind? Read about the spanning trees of the hypercube (the research thread of Section 1.5 and Chapter 3).
For (b): delete the smallest leaf as in the Prüfer code, but write its neighbour into one of two words according to the side of the deleted leaf. Count how long each word is.
For (b): the word recording neighbours on the left side has length \(n-1\) and the other has length \(m-1\).
Many counting problems ask for objects that avoid a list of bad properties: graphs with no isolated vertex, colourings with no monochromatic edge, permutations with no fixed point. Counting the objects that have a given set of bad properties is often easy. The principle of inclusion and exclusion turns these easy counts into the answer.
Theorem 2.6.1 (Inclusion–exclusion). Let \(A_1,\ldots,A_m\) be subsets of a finite set \(X\), and for \(S\subseteq[m]\) write \(A_S=\bigcap_{i\in S}A_i\), with \(A_\varnothing=X\). Then the number of elements of \(X\) in none of the \(A_i\) is \[\Big|X\setminus\bigcup_{i}A_i\Big|=\sum_{S\subseteq[m]}(-1)^{|S|}\,|A_S|.\]
Proof. An element \(x\) that lies in exactly the sets \(A_i\) with \(i\in T\) is counted on the right once for every \(S\subseteq T\), with sign \((-1)^{|S|}\). The total is \(\sum_{S\subseteq T}(-1)^{|S|}=(1-1)^{|T|}\), which is \(1\) if \(T=\varnothing\) and \(0\) otherwise.
The problème des rencontres, how many permutations have no fixed point, was posed by Pierre Rémond de Montmort in 1708 and solved by him and Nicolaus Bernoulli a few years later. Abraham de Moivre used inclusion–exclusion in The Doctrine of Chances (1718).
Corollary 2.6.2. The number of surjections from \([n]\) onto \([k]\) is \(k!\,S(n,k)=\sum_{i=0}^k(-1)^i\binom ki(k-i)^n\), and the number of derangements of \([n]\) is \[D_n=\sum_{i=0}^n(-1)^i\binom ni(n-i)!=n!\sum_{i=0}^n\frac{(-1)^i}{i!}.\]
Proof. For surjections, let \(A_i\) be the maps missing the value \(i\); then \(|A_S|=(k-|S|)^n\). For derangements, let \(A_i\) be the permutations fixing \(i\); then \(|A_S|=(n-|S|)!\).
In graph language, \(D_n\) counts the ways to cover the vertices of the complete digraph by disjoint directed cycles of length at least \(2\), and \(D_n/n!\to1/e\): about \(37\%\) of all permutations are derangements.
Proposition 2.6.3. The number of graphs on \([n]\) with no isolated vertex is \[\sum_{i=0}^n(-1)^i\binom ni2^{\binom{n-i}2}.\]
Proof. Let \(A_v\) be the graphs in which \(v\) is isolated. The graphs in which all vertices of a set \(S\) are isolated are the graphs on the other \(n-|S|\) vertices, so \(|A_S|=2^{\binom{n-|S|}2}\).
The values for \(n=1,\ldots,6\) are \(0, 1, 4, 41, 768, 27449\). Compare them with the numbers \(1,1,4,38,728,26704\) of connected graphs: every connected graph with at least two vertices has no isolated vertex, and for large \(n\) the two counts are close, a first hint of Chapter 6.
Hassler Whitney (1907–1989)
American mathematician, founder of the theory of matroids. In 1932 he expressed the chromatic polynomial as a sum over sets of edges, which is the theorem below.
Theorem 2.6.4 (Whitney). For every graph \(G=(V,E)\) and every positive integer \(k\), \[P(G,k)=\sum_{S\subseteq E}(-1)^{|S|}\,k^{\,c(S)},\] where \(c(S)\) is the number of components of the spanning subgraph \((V,S)\).
Proof. Let \(X\) be the set of all \(k^{|V|}\) colourings and, for an edge \(e\), let \(A_e\) be the colourings in which the ends of \(e\) have the same colour. The proper colourings are those in no \(A_e\). A colouring lies in \(A_S\) exactly when it is constant on each component of \((V,S)\), so \(|A_S|=k^{c(S)}\), and Theorem 2.6.1 gives the formula.
Corollary 2.6.5. \(P(G,k)\) is a polynomial in \(k\) of degree \(n=|V|\), with leading coefficient \(1\), and the coefficient of \(k^{n-1}\) is \(-|E|\).
Proof. Each term of Theorem 2.6.4 is a power of \(k\). Only \(S=\varnothing\) gives \(c(S)=n\), and \(c(S)=n-1\) exactly when \(|S|=1\).
A perfect matching of a bipartite graph with sides \(\{u_1,\ldots,u_n\}\) and \(\{w_1,\ldots,w_n\}\) is a permutation \(\sigma\) with \(u_iw_{\sigma(i)}\) an edge for every \(i\). If \(A=(a_{ij})\) is the \(0/1\) matrix with \(a_{ij}=1\) when \(u_iw_j\) is an edge, the number of perfect matchings is the permanent \[\mathrm{per}(A)=\sum_{\sigma}\prod_{i=1}^na_{i\sigma(i)},\] the determinant without signs. It has \(n!\) terms, but inclusion–exclusion gives a formula with only \(2^n\).
Herbert John Ryser (1923–1985)
American combinatorialist, author of Combinatorial Mathematics (1963), where the formula below appears.
Theorem 2.6.6 (Ryser). For every \(n\times n\) matrix \(A\), \[\mathrm{per}(A)=\sum_{S\subseteq[n]}(-1)^{n-|S|}\prod_{i=1}^n\sum_{j\in S}a_{ij}.\]
Proof. Expanding the product, \(\prod_i\sum_{j\in S}a_{ij}\) is the sum of \(\prod_ia_{if(i)}\) over all maps \(f:[n]\to S\). For a fixed map \(f:[n]\to[n]\) with image \(T\), the term appears for every \(S\supseteq T\), with total sign \(\sum_{S\supseteq T}(-1)^{n-|S|}\), which is \(1\) if \(T=[n]\) and \(0\) otherwise. The maps with image \([n]\) are the permutations.
The same idea counts Hamiltonian cycles: a closed walk of length \(n\) that visits every vertex is a Hamiltonian cycle, and inclusion–exclusion over the set of avoided vertices counts such walks with \(2^n\) matrix powers (Exercise 2.6.6). These are the fastest known exact methods of their kind, and they are still exponential; Chapter 6 explains why nobody expects much better.
from itertools import permutations, combinations
from math import comb, prod
def per_brute(A):
n = len(A)
return sum(prod(A[i][p[i]] for i in range(n)) for p in permutations(range(n)))
def per_ryser(A):
n = len(A)
total = 0
for k in range(n + 1):
for S in combinations(range(n), k):
total += (-1) ** (n - k) * prod(sum(A[i][j] for j in S) for i in range(n))
return total
# Q3 is bipartite: even-weight words against odd-weight words
even = [x for x in range(8) if bin(x).count("1") % 2 == 0]
odd = [x for x in range(8) if bin(x).count("1") % 2 == 1]
A = [[int(bin(u ^ w).count("1") == 1) for w in odd] for u in even]
print("perfect matchings of Q3:", per_brute(A), per_ryser(A))
no_isolated = [sum((-1) ** i * comb(n, i) * 2 ** comb(n - i, 2) for i in range(n + 1)) for n in range(1, 8)]
print("graphs with no isolated vertex:", no_isolated)
def chromatic_whitney(n, E, k):
total = 0
for r in range(len(E) + 1):
for S in combinations(E, r):
parent = list(range(n))
def find(x):
while parent[x] != x: x = parent[x]
return x
for a, b in S:
parent[find(a)] = find(b)
total += (-1) ** r * k ** len({find(v) for v in range(n)})
return total
C5 = [(i, (i + 1) % 5) for i in range(5)]
print("P(C5, k) for k = 0..5:", [chromatic_whitney(5, C5, k) for k in range(6)])
Lab · Inclusion–exclusion visualiser
The reader picks a small graph and a number of colours \(k\). The lab lists the edge sets \(S\) in order of size, shows \((-1)^{|S|}k^{c(S)}\) for each, and accumulates the sum until it reaches \(P(G,k)\), so that the cancellation of the large terms is visible.
This lab is being built for the web edition.
Exercise 2.6.1 Pure
Compute \(D_8\).
Exercise 2.6.2 Pure
How many graphs on \([5]\) have no isolated vertex?
Exercise 2.6.3 Pure
Prove that the coefficient of \(k^{n-2}\) in \(P(G,k)\) is \(\binom{|E|}2-t(G)\), where \(t(G)\) is the number of triangles.
Which edge sets \(S\) have \(c(S)=n-2\)? Two edges, or three edges forming a triangle.
Exercise 2.6.4 Math Olympiad
Prove that the number of permutations of \([n]\) in which \(i+1\) never immediately follows \(i\) is \(D_n+D_{n-1}\).
Let \(A_i\) be the permutations in which \(i+1\) immediately follows \(i\); then \(|A_S|=(n-|S|)!\).
Exercise 2.6.5 Pure
Using Theorem 2.6.4, prove that the coefficients of \(P(G,k)\) alternate in sign.
This is harder than it looks from Theorem 2.6.4 alone; the cleanest proof uses deletion–contraction (Chapter 4). Try it for trees and cycles first.
Exercise 2.6.6 Algorithm
Let \(A\) be the adjacency matrix of a graph on \([n]\). Show that the number of Hamiltonian cycles is \[\frac1{2n}\sum_{S\subseteq[n]}(-1)^{n-|S|}\,\mathrm{tr}\big(A_S^{\,n}\big),\] where \(A_S\) is the submatrix on the rows and columns in \(S\), for \(n\geqslant3\). Deduce an \(O(2^nn^4)\) algorithm, and improve it to polynomial space. (Karp, 1982; Bax, 1993.)
\(\mathrm{tr}(A_S^n)\) counts closed walks of length \(n\) inside \(S\). A closed walk of length \(n\) visiting all \(n\) vertices is a Hamiltonian cycle, traversed from one of \(n\) starting points in one of \(2\) directions.
Exercise 2.6.7 Code
Compute the number of perfect matchings of the \(4\times4\) grid graph \(P_4\,\square\,P_4\) with Ryser’s formula.
Inclusion–exclusion runs over the subsets of a set. Many counting problems have a different natural structure, for example the partitions of a set, ordered by refinement. Möbius inversion, due in this generality to Gian-Carlo Rota, does for every finite partially ordered set what inclusion–exclusion does for subsets. It gives the explicit formula for connected graphs announced in Section 1.10.
Gian-Carlo Rota (1932–1999)
Italian-American mathematician at MIT. His 1964 paper On the foundations of combinatorial theory I: Theory of Möbius functions turned a collection of tricks into a theory.
Combinatorics is an honest subject.
— attributed
Definition 2.7.1. Let \((P,\leqslant)\) be a finite partially ordered set. Its Möbius function \(\mu\) is defined on pairs \(x\leqslant y\) by \[\mu(x,x)=1,\qquad \mu(x,y)=-\sum_{x\leqslant z<y}\mu(x,z)\quad(x<y).\]
Theorem 2.7.2 (Möbius inversion). Let \(f,g\) be functions on a finite poset \(P\). Then \[g(x)=\sum_{y\leqslant x}f(y)\ \text{for all }x\quad\Longleftrightarrow\quad f(x)=\sum_{y\leqslant x}\mu(y,x)\,g(y)\ \text{for all }x.\] The same holds with all inequalities reversed: \(g(x)=\sum_{y\geqslant x}f(y)\) if and only if \(f(x)=\sum_{y\geqslant x}\mu(x,y)g(y)\).
Proof. Write \(\zeta(x,y)=1\) for \(x\leqslant y\). The definition of \(\mu\) says \(\sum_{x\leqslant z\leqslant y}\mu(x,z)\zeta(z,y)=\delta(x,y)\), where \(\delta(x,y)\) is \(1\) if \(x=y\) and \(0\) otherwise. Order the elements of \(P\) compatibly with \(\leqslant\); then \(\zeta\) and \(\mu\) are upper triangular matrices with ones on the diagonal, and the definition says \(\mu\zeta=I\). A left inverse of a square matrix is also a right inverse, so \(\zeta\mu=I\), that is, \(\sum_{x\leqslant z\leqslant y}\mu(z,y)=\delta(x,y)\). Now if \(g(x)=\sum_{y\leqslant x}f(y)\), then \[\sum_{y\leqslant x}\mu(y,x)g(y)=\sum_{z\leqslant x}f(z)\sum_{z\leqslant y\leqslant x}\mu(y,x)=f(x).\] In matrix language, \(g=f\zeta\) implies \(f=g\mu\), and conversely; the reversed version is \(g=\zeta f\) and \(f=\mu g\).
Example 2.7.3. In the poset of subsets of \([m]\) ordered by inclusion, \(\mu(S,T)=(-1)^{|T\setminus S|}\), and Möbius inversion is inclusion–exclusion. In the poset of positive divisors of \(N\) ordered by divisibility, \(\mu(d,e)\) is the number-theoretic Möbius function of \(e/d\).
Definition 2.7.4. The partition lattice \(\Pi_n\) is the set of partitions of \([n]\), ordered by refinement: \(\sigma\leqslant\pi\) if every block of \(\sigma\) is contained in a block of \(\pi\). Its least element \(\hat0\) has \(n\) singleton blocks and its greatest element \(\hat1\) has one block. We write \(|\pi|\) for the number of blocks.
Theorem 2.7.5. In \(\Pi_n\), \(\mu(\hat0,\hat1)=(-1)^{n-1}(n-1)!\). More generally, if \(\sigma\leqslant\pi\) and every block of \(\pi\) is a union of \(k_1,k_2,\ldots\) blocks of \(\sigma\), then \(\mu(\sigma,\pi)=\prod_j(-1)^{k_j-1}(k_j-1)!\).
Proof. Fix a positive integer \(x\). For a partition \(\pi\) let \(g(\pi)=x^{|\pi|}\), the number of maps \([n]\to[x]\) that are constant on every block of \(\pi\), and let \(f(\pi)\) be the number of maps whose kernel (the partition into fibres) is exactly \(\pi\); so \(f(\pi)=x(x-1)\cdots(x-|\pi|+1)\). Every map constant on the blocks of \(\pi\) has a kernel \(\sigma\geqslant\pi\), so \(g(\pi)=\sum_{\sigma\geqslant\pi}f(\sigma)\) and, by Theorem 2.7.2, \[x(x-1)\cdots(x-n+1)=f(\hat0)=\sum_{\sigma}\mu(\hat0,\sigma)\,x^{|\sigma|}.\] Both sides are polynomials in \(x\); comparing the coefficients of \(x^1\), only \(\sigma=\hat1\) contributes on the right, and on the left the coefficient is \((-1)^{n-1}(n-1)!\). The general case follows because the interval \([\sigma,\pi]\) is a product of partition lattices \(\Pi_{k_j}\).
Theorem 2.7.6. The number of connected graphs on \([n]\) is \[\mathcal C_n=\sum_{\pi\in\Pi_n}(-1)^{|\pi|-1}(|\pi|-1)!\prod_{B\in\pi}2^{\binom{|B|}2}.\]
Proof. For a graph \(G\) on \([n]\) let \(\kappa(G)\) be the partition of \([n]\) into the vertex sets of its components. For \(\pi\in\Pi_n\) let \(f(\pi)\) be the number of graphs with \(\kappa(G)=\pi\) and \(g(\pi)\) the number of graphs all of whose edges lie inside blocks of \(\pi\), so \(g(\pi)=\prod_{B\in\pi}2^{\binom{|B|}2}\). A graph has all its edges inside the blocks of \(\pi\) exactly when \(\kappa(G)\leqslant\pi\), so \(g(\pi)=\sum_{\sigma\leqslant\pi}f(\sigma)\). Möbius inversion at \(\pi=\hat1\) and Theorem 2.7.5 give \(\mathcal C_n=f(\hat1)=\sum_\sigma\mu(\sigma,\hat1)g(\sigma)\) with \(\mu(\sigma,\hat1)=(-1)^{|\sigma|-1}(|\sigma|-1)!\).
The same argument works for any property of graphs that is decided component by component. Replacing \(2^{\binom{|B|}2}\) by the number \(2^{\binom{|B|-1}2}\) of even graphs on \(B\) (Theorem 2.1.1) counts the connected even graphs, which are the Eulerian graphs of the next section.
One number, many proofs
This is the second of the five answers for \(\mathcal C_n\) promised in Section 1.10. The first was the recurrence (Theorem 2.2.4); Chapter 5 will show that both are shadows of one identity of power series, \(C(x)=\log G(x)\), whose expansion \(\log(1+u)=u-\frac{u^2}2+\frac{u^3}3-\cdots\) produces exactly the coefficients \((-1)^{k-1}(k-1)!/k!\) of the formula above.
from math import comb, factorial
def set_partitions(items):
if not items:
yield []; return
first, rest = items[0], items[1:]
for p in set_partitions(rest):
yield [[first]] + p
for i in range(len(p)):
yield p[:i] + [[first] + p[i]] + p[i + 1:]
def count_connected(n, per_block):
"""Moebius inversion on the partition lattice for a property decided block by block."""
total = 0
for p in set_partitions(list(range(n))):
k = len(p)
term = (-1) ** (k - 1) * factorial(k - 1)
for B in p:
term *= per_block(len(B))
total += term
return total
all_graphs = lambda b: 2 ** comb(b, 2)
even_graphs = lambda b: 2 ** comb(b - 1, 2)
print("connected graphs: ", [count_connected(n, all_graphs) for n in range(1, 9)])
print("connected even: ", [count_connected(n, even_graphs) for n in range(1, 9)])
Exercise 2.7.1 Pure
Compute the Möbius function of the poset of divisors of \(12\) and use Möbius inversion to count the binary words of length \(6\) that are not a repetition of a shorter word.
A word of length \(n\) is a power of a unique primitive word whose length \(d\) divides \(n\), so \(2^n=\sum_{d\mid n}p(d)\).
Exercise 2.7.2 Pure
How many binary necklaces of length \(6\) (words up to rotation) are primitive?
Each primitive necklace of length \(n\) corresponds to exactly \(n\) primitive words.
Exercise 2.7.3 Pure
Use the method of Theorem 2.7.6 to count the graphs on \([n]\) with exactly two components, and check your formula for \(n=4\).
Möbius inversion is not needed: a graph with two components is a choice of the block containing \(1\) and a connected graph on each block.
Exercise 2.7.4 Pure
Verify Theorem 2.7.5 directly for \(n=3\) by computing \(\mu\) on all of \(\Pi_3\).
Exercise 2.7.5 Code
Adapt the program of this section to count the connected triangle-free graphs on \([n]\) for \(n\leqslant6\). Triangle-freeness is decided component by component, so you only need the number of triangle-free graphs on a block, which you can count by brute force.
Exercise 2.7.6 Research Project
A small research project: the bond lattice. For a graph \(G\) on \([n]\), a partition \(\pi\) of \([n]\) is a bond if every block induces a connected subgraph of \(G\). The bonds form a poset \(L(G)\) under refinement.
Show that \(L(K_n)=\Pi_n\) and that \(L(T)\) is a Boolean lattice for a tree \(T\).
Prove Rota’s formula \(P(G,x)=\sum_{\pi\in L(G)}\mu(\hat0,\pi)\,x^{|\pi|}\), by the argument of Theorem 2.7.5.
Compute \(L(C_4)\) and its Möbius function, and check (b).
Open-ended: read about the characteristic polynomial of a geometric lattice and its connection with Chapter 4’s Tutte polynomial.
We return to the problem with which graph theory began. Can one walk across each of the seven bridges of Königsberg exactly once? In our language: does the multigraph of the four land masses and seven bridges have an Eulerian trail, a trail that uses every edge exactly once?
Definition 2.8.1. A graph (or multigraph) is Eulerian if it has a closed trail using every edge exactly once, an Eulerian circuit. An Eulerian trail uses every edge exactly once and may end at a different vertex from where it starts.
Lemma 2.8.2. Every multigraph with at least one edge in which every vertex has even degree contains a cycle.
Proof. Remove isolated vertices; every remaining vertex has degree at least \(2\). Walk from any vertex, never leaving along the edge just used; since every degree is at least \(2\) this is always possible, and since the graph is finite some vertex is eventually repeated. The part of the walk between two visits to it is a cycle (for a multigraph, possibly a pair of parallel edges or a loop).
Theorem 2.8.3 (Euler, Hierholzer). Let \(G\) be a connected multigraph with at least one edge. Then \(G\) has an Eulerian circuit if and only if every vertex has even degree, and an Eulerian trail if and only if it has exactly zero or two vertices of odd degree; in the latter case the trail must start at one odd vertex and end at the other.
Proof. A closed trail enters and leaves a vertex the same number of times, so all degrees are even; an open trail does the same except at its two ends. Conversely, induct on the number of edges. If all degrees are even, Lemma 2.8.2 gives a cycle \(C\). Deleting the edges of \(C\) leaves a graph whose degrees are still even; each of its components with an edge meets \(C\) (because \(G\) is connected) and, by induction, has an Eulerian circuit. Walk along \(C\) and, at the first vertex of each such component, detour around its circuit. The result uses every edge exactly once. If exactly two vertices \(u,v\) are odd, add a new edge \(uv\), take an Eulerian circuit of the new multigraph, and remove the new edge to obtain a trail from \(u\) to \(v\).
Carl Hierholzer (1840–1871)
German mathematician. Euler had proved only that the degree condition is necessary; Hierholzer proved it is sufficient. His paper was published in 1873, two years after his death, from notes taken by colleagues.
Example 2.8.4. In the Königsberg multigraph the four land masses have degrees \(5,3,3,3\). All four are odd, so by Theorem 2.8.3 there is no walk crossing every bridge exactly once.
The proof is also an algorithm: Hierholzer’s algorithm finds an Eulerian circuit in time proportional to the number of edges by splicing cycles as above. The directed version is proved the same way: a weakly connected digraph has a directed Eulerian circuit if and only if \(d^+(v)=d^-(v)\) for every vertex.
Theorem 2.8.5. The number of Eulerian graphs on \([n]\), that is, connected simple graphs with all degrees even, is \[\sum_{\pi\in\Pi_n}(-1)^{|\pi|-1}(|\pi|-1)!\prod_{B\in\pi}2^{\binom{|B|-1}2}.\] For \(n=1,\ldots,7\) it is \(1, 0, 1, 3, 38, 720, 26614\).
Proof. A graph has all degrees even exactly when each of its components does, so the argument of Theorem 2.7.6 applies with \(g(\pi)=\prod_B2^{\binom{|B|-1}2}\), by Theorem 2.1.1.
Nicolaas Govert de Bruijn (1918–2012)
Dutch mathematician at Eindhoven. In 1946 he counted the binary sequences named after him; Camille Flye Sainte-Marie had already found the count in 1894, as was discovered in 1975.
Definition 2.8.6. A binary de Bruijn sequence of order \(n\) is a cyclic sequence of \(2^n\) bits in which every binary word of length \(n\) appears exactly once as \(n\) consecutive bits.
For \(n=3\), the cyclic sequence \(00010111\) contains \(000,001,010,101,011,111,110,100\), each once. Such sequences exist for every \(n\): in the de Bruijn digraph whose vertices are the words of length \(n-1\), draw an arc from \(a_1\cdots a_{n-1}\) to \(a_2\cdots a_n\) labeled \(a_1\cdots a_n\). Every vertex has in-degree and out-degree \(2\), and the digraph is strongly connected, so it has a directed Eulerian circuit, and the circuit spells a de Bruijn sequence. Counting the circuits is harder; Chapter 3 proves with the BEST theorem that there are exactly \(2^{2^{n-1}-n}\) binary de Bruijn sequences of order \(n\).
from itertools import combinations, product
def hierholzer(adj, start):
"""Eulerian circuit of a digraph given as {v: [w, ...]} (each list is consumed)."""
stack, circuit = [start], []
while stack:
v = stack[-1]
if adj[v]:
stack.append(adj[v].pop())
else:
circuit.append(stack.pop())
return circuit[::-1]
def de_bruijn(n):
words = ["".join(w) for w in product("01", repeat=n - 1)]
adj = {w: [w[1:] + "1", w[1:] + "0"] for w in words}
circuit = hierholzer(adj, "0" * (n - 1))
return "".join(v[-1] for v in circuit[1:])
for n in range(2, 6):
s = de_bruijn(n)
windows = {(s + s)[i:i + n] for i in range(len(s))}
print(n, s, "all words present:", len(windows) == 2 ** n)
# count de Bruijn sequences of order 4 by brute force over cyclic sequences
n, L = 4, 16
seqs = set()
for bits in product("01", repeat=L):
s = "".join(bits)
if len({(s + s)[i:i + n] for i in range(L)}) == L:
seqs.add(min(s[i:] + s[:i] for i in range(L))) # one representative per rotation class
print("de Bruijn sequences of order 4:", len(seqs), " formula 2^(2^(n-1)-n) =", 2 ** (2 ** (n - 1) - n))
Lab · Euler tour
The reader draws a multigraph or loads the Königsberg bridges. The lab shows the degrees, says whether an Eulerian circuit or trail exists, and animates Hierholzer’s algorithm, splicing one cycle at a time.
This lab is being built for the web edition.
Research thread · Eulerian circuits of complete graphs
For directed graphs the BEST theorem of Chapter 3 counts Eulerian circuits exactly. For undirected graphs no such formula is known, and counting Eulerian circuits of a general graph is #P-complete (Brightwell and Winkler, 2005). Even for \(K_n\) with \(n\) odd only an asymptotic formula is known (McKay and Robinson, 1998). A first step: count the Eulerian circuits of \(K_5\) and \(K_7\) by computer, and compare with the number of Eulerian circuits of the directed graph obtained by replacing each edge by two opposite arcs.
Reading: G. Brightwell and P. Winkler, Counting Eulerian circuits is #P-complete, Proc. ALENEX/ANALCO 2005; B. D. McKay and R. W. Robinson, Asymptotic enumeration of Eulerian circuits in the complete graph, Combin. Probab. Comput. 7 (1998).
Exercise 2.8.1 Pure
How many Eulerian graphs are there on \([6]\)?
Exercise 2.8.2 Pure Math Olympiad
Prove that the edges of a connected graph with exactly \(2k>0\) odd vertices can be split into \(k\) trails, and that fewer than \(k\) trails never suffice.
Add \(k\) new edges pairing up the odd vertices and use Theorem 2.8.3.
Exercise 2.8.3 Informatics Olympiad Algorithm
A set of dominoes is given, each showing two numbers from \(0\) to \(6\). Design a linear-time algorithm that decides whether all of them can be laid in a single chain in which touching halves show the same number, and finds such a chain.
Make a multigraph on \(\{0,\ldots,6\}\) with one edge per domino.
Exercise 2.8.4 Code
Run the program of this section and confirm that there are \(16\) binary de Bruijn sequences of order \(4\). How long would the brute-force count take for order \(5\)?
Exercise 2.8.5 Pure
Prove that a weakly connected digraph with \(d^+(v)=d^-(v)\) for all \(v\) is strongly connected.
Exercise 2.8.6 Pure
Let \(E_k\) be the number of Eulerian graphs on \([k]\), and let \(e_0=1\) and \(e_m=2^{\binom{m-1}2}\) for \(m\geqslant1\). Show that \[2^{\binom{n-1}2}=\sum_{k=1}^{n}\binom{n-1}{k-1}E_k\,e_{n-k}\qquad(n\geqslant1),\] and use it to compute \(E_5\).
Imitate the recurrence of Section 1.10: look at the component containing vertex \(1\).
Part A of this chapter rests on one observation: a graph on \([n]\) is an \(n\times n\) matrix of zeros and ones. Once the graph is a matrix, a whole toolbox becomes available. Matrix products count walks, determinants count trees and matchings, and eigenvalues compress all of this into a handful of numbers. In this section we set up the matrices and learn to count walks; the next four sections build on them.
Definition 3.1.1. Let \(G\) be a graph on \([n]\). Its adjacency matrix is the \(n\times n\) matrix \(A=A(G)\) with \(a_{uv}=1\) if \(uv\in E\) and \(a_{uv}=0\) otherwise. The degree matrix \(D\) is diagonal with \(d_{vv}=\deg(v)\), and the Laplacian is \(L=D-A\). For a multigraph, \(a_{uv}\) is the number of edges joining \(u\) and \(v\); for a digraph, \(a_{uv}\) is the number of arcs from \(u\) to \(v\).
\(A\) is symmetric with zero diagonal, and its row sums are the degrees. The Laplacian has row sums \(0\), so \(L\mathbf 1=0\), where \(\mathbf 1\) is the all-ones vector.
Theorem 3.1.2. For every \(k\geqslant0\) the entry \((A^k)_{uv}\) is the number of walks of length \(k\) from \(u\) to \(v\).
Proof. For \(k=0\) both sides are \(1\) if \(u=v\) and \(0\) otherwise. A walk of length \(k+1\) from \(u\) to \(v\) is a walk of length \(k\) from \(u\) to some \(w\) followed by an edge \(wv\). By induction their number is \(\sum_w(A^k)_{uw}a_{wv}=(A^{k+1})_{uv}\).
Corollary 3.1.3. \(\operatorname{tr}A^2=2|E|\), and \(\operatorname{tr}A^3=6\,t(G)\), where \(t(G)\) is the number of triangles.
Proof. A closed walk of length \(2\) goes along an edge and back: each edge gives two of them, one from each end. A closed walk of length \(3\) is a triangle with a chosen start (\(3\) ways) and direction (\(2\) ways).
Example 3.1.4. For \(K_n\) we have \(A=J-I\), where \(J\) is the all-ones matrix. Since \(J^2=nJ\), the matrices \(I\) and \(J\) commute and the binomial theorem gives \[A^k=\sum_{i=0}^k\binom ki J^i(-I)^{k-i}=(-1)^kI+\frac{(n-1)^k-(-1)^k}{n}\,J.\] So between two different vertices of \(K_n\) there are \(\frac{(n-1)^k-(-1)^k}{n}\) walks of length \(k\); for \(n=5\) and \(k=4\) this is \(51\).
Lothar Collatz (1910–1990)
German numerical analyst. With Ulrich Sinogowitz he wrote the 1957 paper Spektren endlicher Grafen, usually taken as the start of spectral graph theory. He is better known for the \(3x+1\) problem.
Because \(A\) is real and symmetric, it has \(n\) real eigenvalues \(\lambda_1\geqslant\cdots\geqslant\lambda_n\), the spectrum of \(G\), and an orthonormal basis of eigenvectors \(x_1,\ldots,x_n\). Then \(A=\sum_i\lambda_ix_ix_i^{\mathsf T}\) and \(A^k=\sum_i\lambda_i^kx_ix_i^{\mathsf T}\).
Theorem 3.1.5. The number of closed walks of length \(k\) in \(G\) is \(\operatorname{tr}A^k=\sum_{i=1}^n\lambda_i^k\). More generally the number of walks of length \(k\) from \(u\) to \(v\) is \(\sum_i\lambda_i^k\,x_i(u)\,x_i(v)\).
Proof. Take the \((u,v)\) entry of \(A^k=\sum_i\lambda_i^kx_ix_i^{\mathsf T}\) and use Theorem 3.1.2; the trace of a matrix is the sum of its eigenvalues.
So the spectrum alone tells us the number of edges and the number of triangles; for a regular graph it also gives the number of spanning trees, as we shall see in Section 3.2. Here are the spectra of the families of Chapter 1.
Proposition 3.1.6. (a) \(K_n\) has eigenvalues \(n-1\) (once) and \(-1\) (\(n-1\) times).
\(C_n\) has eigenvalues \(2\cos(2\pi j/n)\) for \(j=0,1,\ldots,n-1\).
\(Q_n\) has eigenvalues \(n-2j\) with multiplicity \(\binom nj\), for \(j=0,\ldots,n\).
The Petersen graph has eigenvalues \(3\) (once), \(1\) (five times) and \(-2\) (four times).
Proof. (a) \(J\) has eigenvalues \(n\) (on \(\mathbf 1\)) and \(0\) (on the vectors orthogonal to \(\mathbf 1\)), and \(A=J-I\).
Number the vertices \(0,\ldots,n-1\) along the cycle and let \(\omega=e^{2\pi i j/n}\). The vector \(x(v)=\omega^v\) satisfies \((Ax)(v)=\omega^{v-1}+\omega^{v+1}=(\omega+\omega^{-1})x(v)\), and \(\omega+\omega^{-1}=2\cos(2\pi j/n)\). The \(n\) vectors obtained for \(j=0,\ldots,n-1\) are linearly independent (a Vandermonde matrix).
For a word \(s\in\{0,1\}^n\) let \(x_s(w)=(-1)^{s\cdot w}\). Changing the \(i\)th letter of \(w\) multiplies \(x_s(w)\) by \((-1)^{s_i}\), so \((Ax_s)(w)=\sum_i(-1)^{s_i}x_s(w)=(n-2|s|)\,x_s(w)\), where \(|s|\) is the number of ones in \(s\). These \(2^n\) vectors are orthogonal, and \(\binom nj\) of them have \(|s|=j\).
In the Petersen graph two adjacent vertices have no common neighbour and two non-adjacent vertices have exactly one. Counting walks of length \(2\) gives \(A^2=3I+(J-I-A)\), that is, \(A^2+A-2I=J\). On \(\mathbf 1\) the eigenvalue is \(3\). On a vector orthogonal to \(\mathbf 1\) the right side vanishes, so \(\lambda^2+\lambda-2=0\) and \(\lambda\in\{1,-2\}\). If the multiplicities are \(a\) and \(b\), then \(a+b=9\) and \(3+a-2b=\operatorname{tr}A=0\), so \(a=5\) and \(b=4\).
Example 3.1.7. In the Petersen graph, \(\operatorname{tr}A^3=3^3+5\cdot1-4\cdot8=0\): no triangles. And \(\operatorname{tr}A^5=243+5-128=120\). The graph has girth \(5\), so a closed walk of length \(5\) cannot contain a shorter cycle and must go once around a \(5\)-cycle; each \(5\)-cycle gives \(5\cdot2=10\) such walks (a start and a direction). Hence the Petersen graph has exactly \(12\) five-cycles.
Fix an orientation of each edge and let \(B\) be the \(n\times|E|\) incidence matrix: the column of the edge \(e\) oriented from \(u\) to \(v\) has \(+1\) in row \(u\), \(-1\) in row \(v\) and zeros elsewhere. Then \((BB^{\mathsf T})_{uu}=\deg(u)\) and \((BB^{\mathsf T})_{uv}=-a_{uv}\) for \(u\neq v\), so \[L=BB^{\mathsf T}\qquad\text{and}\qquad x^{\mathsf T}Lx=\sum_{uv\in E}(x_u-x_v)^2.\] The orientation does not matter. The quadratic form shows that \(L\) is positive semidefinite, with eigenvalues \(0=\mu_1\leqslant\mu_2\leqslant\cdots\leqslant\mu_n\).
Proposition 3.1.8. The multiplicity of the eigenvalue \(0\) of \(L\) is the number of components of \(G\). In particular \(\mu_2>0\) if and only if \(G\) is connected.
Proof. \(Lx=0\) holds exactly when \(x^{\mathsf T}Lx=0\), that is, when \(x_u=x_v\) for every edge \(uv\), that is, when \(x\) is constant on each component. These vectors form a space of dimension \(\kappa(G)\).
For a \(d\)-regular graph \(L=dI-A\), so the Laplacian eigenvalues are \(d-\lambda_i\). For example \(K_n\) has Laplacian eigenvalues \(0\) and \(n\) (\(n-1\) times), \(Q_n\) has \(2j\) with multiplicity \(\binom nj\), and the Petersen graph has \(0\), \(2\) (five times) and \(5\) (four times).
Gustav Kirchhoff wrote down the Laplacian of an electrical network in 1847, nearly a century before anyone spoke of the spectrum of a graph. The next section is his theorem.
import numpy as np
import networkx as nx
def closed_walks(G, k):
lam = np.linalg.eigvalsh(nx.to_numpy_array(G))
return round(sum(lam ** k))
P = nx.petersen_graph()
print("Petersen spectrum:", np.round(sorted(np.linalg.eigvalsh(nx.to_numpy_array(P))), 6))
print("closed walks of length 3, 4, 5:", [closed_walks(P, k) for k in (3, 4, 5)])
print("five-cycles:", closed_walks(P, 5) // 10)
# walks of length k between two vertices of K_5, by matrix power and by formula
A = np.ones((5, 5), dtype=int) - np.eye(5, dtype=int)
for k in range(1, 7):
print(k, np.linalg.matrix_power(A, k)[0, 1], (4 ** k - (-1) ** k) // 5)
# Laplacian eigenvalues of Q_4: 2j with multiplicity C(4, j)
L = nx.laplacian_matrix(nx.hypercube_graph(4)).toarray()
print(np.round(sorted(np.linalg.eigvalsh(L)), 6))
Exercise 3.1.1 Pure
Show that the number of closed walks of length \(k\) in \(Q_n\) is \(\sum_{j=0}^n\binom nj(n-2j)^k\). Compute it for \(n=3\) and \(k=4\).
Exercise 3.1.2 Math Olympiad
A bug walks on the edges of a cube, moving to a neighbouring corner every minute. In how many ways can it get from a corner to the opposite corner in exactly \(5\) minutes?
Use the second formula of Theorem 3.1.5 with the eigenvectors \(x_s(w)=(-1)^{s\cdot w}/\sqrt8\).
The answer is \(\frac18\big(3^5-3\cdot1^5+3\cdot(-1)^5-(-3)^5\big)\).
Exercise 3.1.3 Pure
Show that the number of \(4\)-cycles of a graph is \(\frac18\Big(\operatorname{tr}A^4-2\sum_v\deg(v)^2+2|E|\Big)\). Use it to show that the Petersen graph has no \(4\)-cycles and that \(K_{3,3}\) has \(9\).
A closed walk of length \(4\) either goes around a \(4\)-cycle, or goes along an edge and back twice, or goes along two different edges at one vertex. Count each kind.
Exercise 3.1.4 Pure
Show that if \(G\) is bipartite, then its spectrum is symmetric about \(0\): \(\lambda\) and \(-\lambda\) have the same multiplicity.
If \(x\) is an eigenvector, change the sign of \(x\) on one side of the bipartition.
Exercise 3.1.5 Code
Compute the number of closed walks of length \(6\) in the Petersen graph from its spectrum, and check it with a matrix power.
Exercise 3.1.6 Algorithm Informatics Olympiad
Explain how to compute the number of walks of length \(k\) between two vertices of a graph on \(n\) vertices with \(O(n^3\log k)\) arithmetic operations. Why is it a bad idea to use floating-point eigenvalues for large \(k\)?
Square and multiply: \(A^{2j}=(A^j)^2\).
In Chapter 2 we counted the spanning trees of \(K_n\) three ways, and every proof used the symmetry of \(K_n\). Kirchhoff’s theorem counts the spanning trees of any graph, and the answer is a determinant: something a computer evaluates in polynomial time even when the number itself is astronomically large.
Gustav Kirchhoff (1824–1887)
German physicist. As a student he stated the two circuit laws that carry his name, and in 1847 he showed how to solve an electrical network using its spanning trees. He later founded spectroscopy with Robert Bunsen.
Definition 3.2.1. For a vertex \(i\), the reduced Laplacian \(L_i\) is obtained from \(L\) by deleting row \(i\) and column \(i\). As in Chapter 1, \(\tau(G)\) denotes the number of spanning trees of \(G\).
Theorem 3.2.2 (Matrix-Tree Theorem). For every multigraph \(G\) (without loops) on \([n]\) and every vertex \(i\), \[\tau(G)=\det L_i.\] Equivalently, if \(0=\mu_1\leqslant\mu_2\leqslant\cdots\leqslant\mu_n\) are the Laplacian eigenvalues, then \(\tau(G)=\frac1n\,\mu_2\mu_3\cdots\mu_n\).
The proof needs one fact from linear algebra.
Lemma 3.2.3 (Cauchy–Binet). Let \(M\) be a \(p\times q\) matrix and \(N\) a \(q\times p\) matrix with \(p\leqslant q\). Then \[\det(MN)=\sum_{S}\det M[S]\,\det N[S],\] where \(S\) runs over the \(p\)-subsets of \([q]\), \(M[S]\) keeps the columns of \(M\) in \(S\) and \(N[S]\) keeps the rows of \(N\) in \(S\).
Proof. Both sides are multilinear in the rows of \(M\) and in the columns of \(N\), so it is enough to check them when every row of \(M\) and every column of \(N\) is a standard basis vector. Write \(M\)’s row \(r\) as \(e_{\alpha(r)}^{\mathsf T}\) and \(N\)’s column \(r\) as \(e_{\beta(r)}\). Then \((MN)_{rs}=[\alpha(r)=\beta(s)]\). If \(\alpha\) is not injective, \(M\) has two equal rows, and both sides vanish. Otherwise the only \(S\) that can contribute is the image of \(\alpha\), and both sides equal \(\operatorname{sign}\) of the permutation \(\beta^{-1}\alpha\) when \(\beta\) has the same image, and \(0\) when it does not.
Lemma 3.2.4. Let \(B\) be an incidence matrix of \(G\) and \(B_i\) the matrix obtained by deleting row \(i\). For a set \(S\) of \(n-1\) edges, \(\det B_i[S]=\pm1\) if \(S\) is the edge set of a spanning tree, and \(\det B_i[S]=0\) otherwise.
Proof. If \(S\) is not a tree, then the spanning subgraph \((V,S)\), having \(n-1\) edges, is disconnected (Theorem 1.6.3). Let \(C\) be a component not containing \(i\). Every column of \(B_i[S]\) has either both nonzero entries in rows of \(C\) or none, so the rows of \(C\) add up to zero, and the determinant is \(0\).
If \(S\) is a spanning tree, it has a leaf \(v\neq i\) (Lemma 1.6.2). Row \(v\) of \(B_i[S]\) has a single nonzero entry \(\pm1\), in the column of the leaf edge. Expanding along this row leaves the matrix of the tree \(S\) minus \(v\) with the same vertex \(i\) deleted, and induction gives \(\pm1\).
Proof of Theorem 3.2.2. Since \(L=BB^{\mathsf T}\), deleting row and column \(i\) gives \(L_i=B_iB_i^{\mathsf T}\). By Lemma 3.2.3 and Lemma 3.2.4, \[\det L_i=\sum_{|S|=n-1}\big(\det B_i[S]\big)^2=\tau(G).\] For the second form, the coefficient of \(x\) in \(\det(xI-L)=x\prod_{j\geqslant2}(x-\mu_j)\) is \((-1)^{n-1}\mu_2\cdots\mu_n\). Expanding the determinant, the same coefficient is \((-1)^{n-1}\sum_i\det L_i=(-1)^{n-1}n\,\tau(G)\).
Example 3.2.5. For \(K_4\) minus an edge, with vertices \(1,2,3,4\) and the edge \(12\) missing, \[L=\begin{pmatrix}2&0&-1&-1\\0&2&-1&-1\\-1&-1&3&-1\\-1&-1&-1&3\end{pmatrix},\qquad \det L_4=\det\begin{pmatrix}2&0&-1\\0&2&-1\\-1&-1&3\end{pmatrix}=8.\] Of the \(16\) spanning trees of \(K_4\), exactly \(8\) avoid the edge \(12\), since each tree has \(3\) of the \(6\) edges and by symmetry each edge lies in \(16\cdot3/6=8\) trees.
Corollary 3.2.6. (a) \(\tau(K_n)=n^{n-2}\).
\(\tau(K_{m,n})=m^{n-1}n^{m-1}\).
\(\tau(Q_n)=2^{2^n-n-1}\prod_{j=1}^n j^{\binom nj}\).
\(\tau\) of the Petersen graph is \(2000\).
\(\tau(C_n)=n\).
Proof. Use the eigenvalue form of Theorem 3.2.2.
The Laplacian eigenvalues are \(0\) and \(n\) (\(n-1\) times), so \(\tau=n^{n-1}/n\). This is Cayley’s formula once more.
The Laplacian of \(K_{m,n}\) has eigenvalues \(0\), \(m+n\), \(n\) (\(m-1\) times) and \(m\) (\(n-1\) times): on a vector supported on the \(m\)-side and summing to \(0\), \(L\) acts as multiplication by \(n\), and symmetrically. So \(\tau=\frac1{m+n}(m+n)n^{m-1}m^{n-1}\).
The eigenvalues are \(2j\) with multiplicity \(\binom nj\), so \(\tau=2^{-n}\prod_{j\geqslant1}(2j)^{\binom nj}\), and \(\sum_{j\geqslant1}\binom nj=2^n-1\).
\(\frac1{10}\cdot2^5\cdot5^4=2000\).
The eigenvalues are \(2-2\cos(2\pi j/n)=4\sin^2(\pi j/n)\), and the classical identity \(\prod_{j=1}^{n-1}2\sin(\pi j/n)=n\) gives \(\tau=n^2/n\). Of course \(\tau(C_n)=n\) is obvious directly: delete one of the \(n\) edges.
For \(Q_3\) formula (c) gives \(2^4\cdot1^3\cdot2^3\cdot3=384\), and for \(Q_4\) it gives \(42\,467\,328\). No proof of (c) by a bijection is known, and finding one is the research thread of this section.
Proposition 3.2.7. If \(G\) and \(H\) have Laplacian eigenvalues \(\mu_1,\ldots,\mu_n\) and \(\nu_1,\ldots,\nu_m\), then the Cartesian product \(G\,\square\,H\) has Laplacian eigenvalues \(\mu_i+\nu_j\). Hence \[\tau(G\,\square\,H)=\frac1{nm}\prod_{(i,j)\neq(1,1)}(\mu_i+\nu_j).\]
Proof. The Laplacian of \(G\,\square\,H\) is \(L_G\otimes I_m+I_n\otimes L_H\). If \(L_Gx=\mu x\) and \(L_Hy=\nu y\), it maps \(x\otimes y\) to \((\mu+\nu)\,x\otimes y\), and the \(nm\) vectors \(x_i\otimes y_j\) form a basis.
Since \(Q_n=Q_{n-1}\,\square\,K_2\), this gives the spectrum of \(Q_n\) again. It also handles grids \(P_m\,\square\,P_n\), whose path factors have Laplacian eigenvalues \(2-2\cos(\pi j/n)\), \(j=0,\ldots,n-1\); the \(3\times3\) grid has \(192\) spanning trees and the \(4\times4\) grid has \(100\,352\).
from fractions import Fraction
import networkx as nx
def det(M):
# exact determinant by Gaussian elimination over the rationals
M = [[Fraction(x) for x in row] for row in M]
n, d = len(M), Fraction(1)
for c in range(n):
p = next((r for r in range(c, n) if M[r][c] != 0), None)
if p is None:
return 0
if p != c:
M[c], M[p] = M[p], M[c]; d = -d
d *= M[c][c]
for r in range(c + 1, n):
f = M[r][c] / M[c][c]
M[r] = [a - f * b for a, b in zip(M[r], M[c])]
return int(d)
def tau(G):
L = nx.laplacian_matrix(G, nodelist=list(G)).toarray().tolist()
return det([row[1:] for row in L[1:]])
print("K_n: ", [tau(nx.complete_graph(n)) for n in range(2, 9)])
print("Q_n: ", [tau(nx.hypercube_graph(n)) for n in range(1, 5)])
print("K_3,4:", tau(nx.complete_bipartite_graph(3, 4)), "= 3^3 * 4^2 =", 3**3 * 4**2)
print("Petersen:", tau(nx.petersen_graph()))
print("grids:", tau(nx.grid_2d_graph(3, 3)), tau(nx.grid_2d_graph(4, 4)))
print("wheels W_n:", [tau(nx.wheel_graph(n + 1)) for n in range(3, 9)])
print("ladders P_2 x P_n:", [tau(nx.grid_2d_graph(2, n)) for n in range(1, 9)])
Research thread · A bijective proof for the cube
Formula (c) of Corollary 3.2.6 is a product of small integers, which usually means that a bijection is hiding behind it. R. Stanley asked for a combinatorial proof, in the spirit of the Prüfer code, that \(\tau(Q_n)=2^{2^n-n-1}\prod_j j^{\binom nj}\). O. Bernardi gave a combinatorial explanation of part of the formula, through a weighted count of spanning trees of products of graphs. Read his paper, find out exactly which part of the formula is still without a bijective proof, and test your own ideas on \(Q_3\), which has \(384=2^7\cdot3\) spanning trees.
Reading: O. Bernardi, On the spanning trees of the hypercube and other products of graphs, Electron. J. Combin. 19(4) (2012); R. P. Stanley, Algebraic Combinatorics, Chapter 9.
Exercise 3.2.1 Pure
Show that every edge of \(K_n\) lies in exactly \(2n^{n-3}\) spanning trees, and deduce that \(\tau(K_n-e)=(n-2)n^{n-3}\).
Exercise 3.2.2 Pure
Show that the ladder \(P_2\,\square\,P_n\) has \(\tau_n\) spanning trees, where \(\tau_1=1\), \(\tau_2=4\) and \(\tau_n=4\tau_{n-1}-\tau_{n-2}\). Compute \(\tau_6\).
Use Proposition 3.2.7: the eigenvalues are \(\nu_j\) and \(\nu_j+2\), where \(\nu_j=2-2\cos(\pi j/n)\).
Alternatively, wait for the transfer-matrix method of Chapter 4.
Exercise 3.2.3 Pure Code
The fan \(F_n\) is a path \(P_n\) joined to one extra vertex, and the wheel is \(W_n=C_n+K_1\). Compute \(\tau(F_n)\) and \(\tau(W_n)\) for \(n\leqslant8\) with the program of this section and recognise the Fibonacci numbers \(F_{2n}\) and the Lucas numbers \(L_{2n}-2\). (A proof by recurrences comes in Chapter 4.)
Exercise 3.2.4 Pure
Use Proposition 3.2.7 to show that the prism \(C_n\,\square\,K_2\) has \(\frac n2\Big((2+\sqrt3)^n+(2-\sqrt3)^n-2\Big)\) spanning trees.
Exercise 3.2.5 Pure
Show that \(\tau(G)\leqslant\frac1n\Big(\frac{2|E|}{n-1}\Big)^{n-1}\) for every graph on \(n\) vertices, with equality for \(K_n\).
Apply the inequality between arithmetic and geometric means to \(\mu_2,\ldots,\mu_n\), whose sum is \(\operatorname{tr}L=2|E|\).
Exercise 3.2.6 Computer Science Algorithm
The number of spanning trees of a \(100\times100\) grid has almost \(5000\) digits. Explain why computing it with the Matrix-Tree Theorem in exact integer arithmetic is still feasible, and why floating-point elimination is not.
Exercise 3.2.7 Research Project
A small project: Kirchhoff’s other theorem. In an electrical network with unit resistors, the effective resistance between the ends of an edge \(uv\) equals the fraction of spanning trees that contain \(uv\).
For 2, each spanning tree contributes \(n-1\) edges.
For 3, by symmetry all \(12\) edges have the same resistance.
Kirchhoff’s theorem has a directed version, and the directed version counts something that looks unrelated: Eulerian circuits. This section proves both and then counts de Bruijn sequences, completing the story begun in Section 2.8.
Definition 3.3.1. Let \(D\) be a digraph and \(r\) a vertex. A spanning arborescence converging to \(r\) is a set of arcs in which every vertex \(v\neq r\) has exactly one outgoing arc, \(r\) has none, and following the arcs from any vertex leads to \(r\). Forgetting directions, it is a spanning tree. We write \(t_r(D)\) for their number.
Let \(L^{+}=D^{+}-A\), where \(D^{+}\) is the diagonal matrix of out-degrees and \(a_{uv}\) is the number of arcs from \(u\) to \(v\) (loops are ignored). Its row sums are \(0\).
W. T. Tutte (1917–2002)
British–Canadian mathematician. At Bletchley Park he worked out the structure of the German Lorenz cipher from intercepted text alone. After the war he became one of the founders of modern graph theory, at Toronto and then at Waterloo.
Theorem 3.3.2 (Tutte, 1948). For every digraph \(D\) and every vertex \(r\), \(t_r(D)=\det L^{+}_r\), where \(L^{+}_r\) is \(L^{+}\) with row and column \(r\) deleted.
Proof. Write \(e_v\) for the standard basis vectors indexed by \(V\setminus\{r\}\) and put \(e_r=0\). Row \(v\) of \(L^{+}_r\) is \(\sum(e_v-e_w)\), the sum running over the arcs \(vw\) leaving \(v\). The determinant is linear in each row, so \[\det L^{+}_r=\sum_f\det\big(e_v-e_{f(v)}\big)_{v\neq r},\] where \(f\) runs over the ways to choose one outgoing arc \(v\to f(v)\) for each \(v\neq r\). The chosen arcs form a functional digraph on \(V\) in which \(r\) has no outgoing arc. If they contain a cycle avoiding \(r\), the rows of the vertices of this cycle add up to zero and the term vanishes. Otherwise the arcs form an arborescence converging to \(r\). List the vertices so that each comes after the vertex its arc points to; then the matrix is triangular with ones on the diagonal and the term equals \(1\).
For a graph, replacing each edge by two opposite arcs gives \(L^{+}=L\), and an arborescence converging to \(r\) is just a spanning tree. So Theorem 3.3.2 contains Theorem 3.2.2.
An Eulerian circuit of a digraph is a closed walk that uses every arc exactly once; we regard two circuits as the same when one is a cyclic shift of the other. A connected digraph has one exactly when \(d^{+}(v)=d^{-}(v)\) for every \(v\), by the directed version of Theorem 2.8.3.
Theorem 3.3.3 (BEST theorem). Let \(D\) be a connected digraph with \(d^{+}(v)=d^{-}(v)\) for every vertex. Then \(t_r(D)\) is the same for every vertex \(r\), and the number of Eulerian circuits of \(D\) is \[\mathrm{ec}(D)=t_r(D)\prod_{v\in V}\big(d^{+}(v)-1\big)!.\]
BEST stands for de Bruijn, van Aardenne-Ehrenfest, Smith and Tutte. Smith and Tutte found the formula in 1941; Tatyana van Aardenne-Ehrenfest and Nicolaas de Bruijn rediscovered it in 1951 while counting de Bruijn sequences.
Proof. Fix a vertex \(r\) and an arc \(e\) leaving \(r\). Every circuit can be written in exactly one way as a walk starting with \(e\), so we count those walks.
Given such a walk \(W\), for each \(v\neq r\) mark the arc by which \(W\) leaves \(v\) for the last time. The marked arcs form an arborescence converging to \(r\): each \(v\neq r\) has one marked arc, and following marked arcs only moves to vertices that are left for the last time later, so it ends at \(r\). Record also, for each vertex, the order in which \(W\) uses the other outgoing arcs: at \(r\), the \(d^{+}(r)-1\) arcs other than \(e\); at \(v\neq r\), the \(d^{+}(v)-1\) unmarked arcs.
Conversely, given an arborescence \(T\) and these orders, walk from \(r\) along \(e\), and on each visit to a vertex leave by the next unused arc in its order, using the arc of \(T\) only when all others are used. The walk can only get stuck at \(r\), because \(d^{+}=d^{-}\); when it stops there all arcs at \(r\) are used. If some arc were unused, its tail \(v\) would have its \(T\)-arc unused, and then so would the head of that arc, and so on up to \(r\), a contradiction. So the walk is an Eulerian circuit, and the two constructions are inverse. Counting the choices gives \(t_r(D)\,(d^{+}(r)-1)!\prod_{v\neq r}(d^{+}(v)-1)!\). Since the left side does not depend on \(r\), neither does \(t_r(D)\).
Example 3.3.4. Let \(K_n^{*}\) be the complete digraph with both arcs between every two vertices. Its arborescences converging to \(r\) correspond to the labeled trees on \([n]\) (orient every edge towards \(r\)), so \(t_r=n^{n-2}\), and \[\mathrm{ec}(K_n^{*})=n^{n-2}\big((n-2)!\big)^n.\] For \(n=3\) this is \(3\) and for \(n=4\) it is \(16\cdot2^4=256\).
We extend Definition 2.8.6 to any alphabet: a de Bruijn sequence of order \(n\) over an alphabet of size \(k\) is a cyclic word of length \(k^n\) in which every word of length \(n\) appears exactly once as a block of consecutive letters. Such a sequence is the same thing as an Eulerian circuit of the de Bruijn digraph \(B(k,n-1)\), whose vertices are the \(k^{n-1}\) words of length \(n-1\) and which has an arc \(a_1\cdots a_{n-1}\to a_2\cdots a_n\) for each word \(a_1\cdots a_n\).
Theorem 3.3.5. The number of de Bruijn sequences of order \(n\) over \(k\) letters, counted as cyclic words, is \[\frac{(k!)^{k^{n-1}}}{k^{n}}.\] For \(k=2\) this is \(2^{2^{n-1}-n}\).
Proof. Write \(N=k^{n-1}\) and let \(A\) be the adjacency matrix of \(B(k,n-1)\). A walk of length \(n-1\) can go from any word to any word in exactly one way, since it must append the letters of the target, so \(A^{n-1}=J\). Hence every eigenvalue of \(A\) satisfies \(\lambda^{n-1}\in\{N,0\}\); the eigenvalue \(k\) belongs to \(\mathbf 1\), and since \(\operatorname{tr}A^{j(n-1)}=\operatorname{tr}J^j=N^j\) for all \(j\), all other eigenvalues are \(0\). Every vertex has out-degree \(k\), so \(L^{+}=kI-A\) has eigenvalues \(0\) (once) and \(k\) (\(N-1\) times).
As in the proof of Theorem 3.2.2, the coefficient of \(x\) in \(\det(xI-L^{+})\) is \((-1)^{N-1}\sum_r\det L^{+}_r\), and all \(t_r\) are equal by Theorem 3.3.3. So \(t_r=\frac1Nk^{N-1}=k^{N-n}\), and the BEST theorem gives \(k^{N-n}\big((k-1)!\big)^N=(k!)^N/k^n\) circuits.
For \(k=2\) and \(n=4\) there are \(2^{8-4}=16\) sequences, the number found by brute force in Section 2.8; for \(k=3\) and \(n=2\) there are \(6^3/9=24\).
import itertools as it
from fractions import Fraction
from math import factorial
def det(M):
M = [[Fraction(x) for x in row] for row in M]
n, d = len(M), Fraction(1)
for c in range(n):
p = next((r for r in range(c, n) if M[r][c] != 0), None)
if p is None: return 0
if p != c: M[c], M[p] = M[p], M[c]; d = -d
d *= M[c][c]
for r in range(c + 1, n):
f = M[r][c] / M[c][c]
M[r] = [a - f * b for a, b in zip(M[r], M[c])]
return int(d)
def debruijn_count(k, n):
verts = ["".join(w) for w in it.product("0123456789"[:k], repeat=n - 1)]
idx = {v: i for i, v in enumerate(verts)}
N = len(verts)
L = [[0] * N for _ in range(N)]
for v in verts:
for a in "0123456789"[:k]:
w = (v + a)[1:]
if w != v: # loops do not matter
L[idx[v]][idx[v]] += 1
L[idx[v]][idx[w]] -= 1
t = det([row[1:] for row in L[1:]]) # arborescences converging to 00...0
return t * factorial(k - 1) ** N # BEST theorem
for k, n in [(2, 2), (2, 3), (2, 4), (2, 5), (3, 2), (3, 3), (4, 2)]:
print(k, n, debruijn_count(k, n), "formula", factorial(k) ** (k ** (n - 1)) // k ** n)
Exercise 3.3.1 Pure
Show that in a digraph with \(d^{+}(v)=d^{-}(v)\) for all \(v\), the matrix \(L^{+}\) also has column sums \(0\), and use this to give a direct proof that all the minors \(\det L^{+}_r\) are equal.
The adjugate of a matrix with zero row sums and zero column sums is a multiple of \(J\).
Exercise 3.3.2 Pure
Count the Eulerian circuits of \(K_5^{*}\).
Exercise 3.3.3 Code
Count the Eulerian circuits of the undirected graph \(K_5\) by a depth-first search, counting a circuit and its reversal separately. You should find \(264\). Why can the BEST theorem not be applied directly?
Each Eulerian circuit of \(K_5\) gives a circuit of some Eulerian orientation of \(K_5\), so \(\mathrm{ec}=\sum_{O}\mathrm{ec}(O)\) over Eulerian orientations \(O\). The difficulty is that there are many orientations.
Exercise 3.3.4 Pure Math Olympiad
A binary necklace lock has a keypad with the digits \(0\) and \(1\) and opens as soon as the last four digits typed form the code. What is the shortest sequence of key presses that is sure to open it, whatever the code? How many such shortest sequences are there?
A sequence of length \(2^4+3\) works if and only if it is a de Bruijn sequence of order \(4\) cut open and extended by its first three letters.
Exercise 3.3.5 Research Project
A small project: Eulerian orientations. Let \(\varepsilon(G)\) be the number of Eulerian orientations of a graph with all degrees even.
A determinant is a signed sum over permutations, and a count is an unsigned sum. The Matrix-Tree Theorem worked because all the signs turned out to be squares. In this section the signs cancel in pairs instead: the determinant of a matrix of path counts counts families of paths that never meet.
Definition 3.4.1. Let \(D\) be an acyclic digraph with sources \(A_1,\ldots,A_k\) and sinks \(B_1,\ldots,B_k\), and let \(e(A,B)\) be the number of directed paths from \(A\) to \(B\). A path system is a permutation \(\sigma\) of \([k]\) together with paths \(P_i\) from \(A_i\) to \(B_{\sigma(i)}\). It is non-intersecting if no two of the paths share a vertex.
Theorem 3.4.2 (Lindström–Gessel–Viennot). With \(M=\big(e(A_i,B_j)\big)_{i,j=1}^k\), \[\det M=\sum_{(\sigma,P)}\operatorname{sign}(\sigma),\] the sum running over the non-intersecting path systems. In particular, if every non-intersecting system has \(\sigma=\mathrm{id}\), then \(\det M\) is the number of non-intersecting systems.
Proof. Expanding the determinant, \(\det M=\sum_\sigma\operatorname{sign}(\sigma)\prod_ie(A_i,B_{\sigma(i)})\) is the signed number of all path systems. We pair off the intersecting ones. In an intersecting system let \(i\) be the smallest index whose path meets another path, let \(v\) be the first vertex on \(P_i\) that lies on another path, and let \(j\) be the smallest index \(\neq i\) with \(v\in P_j\). Swap the parts of \(P_i\) and \(P_j\) after \(v\). The new system uses the same vertices, so it is still intersecting and the same \(i\), \(v\) and \(j\) are found again; swapping twice gives back the original system. The swap exchanges \(\sigma(i)\) and \(\sigma(j)\), so it changes the sign. Hence the intersecting systems cancel, and only the non-intersecting ones remain.
The lemma was found by Bernt Lindström in 1973, in a paper on matroids, and made famous by Ira Gessel and Gérard Viennot, who used it in 1985 to count plane partitions. Samuel Karlin and James McGregor had a probabilistic version in 1959: non-colliding random walks.
The typical application is to lattice paths in the plane, with unit steps east and north. If the sources lie on a line running from top-left to bottom-right and the sinks lie on another such line, in the same order, then a path from \(A_1\) to \(B_2\) and a path from \(A_2\) to \(B_1\) must cross. So only \(\sigma=\mathrm{id}\) survives.
Figure 3.4.3. Two non-intersecting lattice paths. A path from \(A_1\) to \(B_2\) would have to cross every path from \(A_2\) to \(B_1\).
Example 3.4.4. In Figure 3.4.3, \(A_1=(0,2)\), \(A_2=(2,0)\), \(B_1=(4,6)\) and \(B_2=(6,4)\). A lattice path from \((a,b)\) to \((c,d)\) is a word with \(c-a\) letters E and \(d-b\) letters N, so there are \(\binom{(c-a)+(d-b)}{c-a}\) of them. Hence the number of pairs of non-intersecting paths is \[\det\begin{pmatrix}\binom84&\binom86\\[2pt]\binom82&\binom84\end{pmatrix}=70^2-28^2=4116.\]
Percy MacMahon (1854–1929)
British artillery officer and mathematician, the author of the two-volume Combinatory Analysis (1915–16). He found the formula for plane partitions in a box below, and he designed puzzles with coloured tiles.
Definition 3.4.5. A plane partition in an \(a\times b\times c\) box is an \(a\times b\) array of integers from \(0\) to \(c\) that is weakly decreasing along every row and down every column. Equivalently, it is a stack of unit cubes pushed into a corner of the box.
Theorem 3.4.6 (MacMahon). The number of plane partitions in an \(a\times b\times c\) box is \[\det\left[\binom{b+c}{b-i+j}\right]_{i,j=1}^a=\prod_{i=1}^a\prod_{j=1}^b\prod_{k=1}^c\frac{i+j+k-1}{i+j+k-2}.\]
Proof. We prove the determinant formula; the product formula is the evaluation of this determinant, which we do not reproduce. Row \(i\) of the array is a partition with at most \(b\) parts, each at most \(c\), so its Young diagram fits in a \(b\times c\) rectangle, and the boundary of the diagram is a lattice path with \(b\) steps east and \(c\) steps north. Start the path of row \(i\) at \(A_i=(-i,i)\) and end it at \(B_i=(b-i,c+i)\). The rows decrease downwards, so without the shifts the paths would be nested and could touch; the shift by \((-i,i)\) pulls them apart, and one checks that the row conditions become exactly the condition that the paths do not meet. The number of paths from \(A_i\) to \(B_j\) is \(\binom{b+c}{b-j+i}\), and by Theorem 3.4.2 the number of non-intersecting systems is the determinant (transposing does not change it).
For the \(2\times2\times2\) box the determinant is \(\binom42^2-\binom41\binom43=20\); for \(2\times3\times3\) it is \(175\); for the \(3\times3\times3\) box it is \(980\). A plane partition in a box, seen from the corner, is a tiling of a hexagon with sides \(a,b,c,a,b,c\) by rhombi, so the same numbers count lozenge tilings.
from math import comb, prod
from fractions import Fraction
import itertools as it
import sympy as sp
def lgv_box(a, b, c):
return sp.Matrix(a, a, lambda i, j: comb(b + c, b - i + j)).det()
def macmahon(a, b, c):
num = prod(i + j + k - 1 for i in range(1, a + 1) for j in range(1, b + 1) for k in range(1, c + 1))
den = prod(i + j + k - 2 for i in range(1, a + 1) for j in range(1, b + 1) for k in range(1, c + 1))
return Fraction(num, den)
def brute(a, b, c):
# count a x b arrays with entries 0..c, decreasing along rows and columns
cnt = 0
for vals in it.product(range(c + 1), repeat=a * b):
M = [vals[r * b:(r + 1) * b] for r in range(a)]
if all(M[r][s] >= M[r][s + 1] for r in range(a) for s in range(b - 1)) and \
all(M[r][s] >= M[r + 1][s] for r in range(a - 1) for s in range(b)):
cnt += 1
return cnt
for box in [(1, 2, 3), (2, 2, 2), (2, 3, 3), (3, 3, 3)]:
print(box, lgv_box(*box), macmahon(*box), brute(*box))
Exercise 3.4.1 Pure
Use Theorem 3.4.2 to show that the Hankel determinants of the Catalan numbers satisfy \(\det[\mathrm{Cat}_{i+j}]_{i,j=0}^{n-1}=1\) for every \(n\).
\(\mathrm{Cat}_m\) counts lattice paths from \((0,0)\) to \((2m,0)\) with steps \((1,1)\) and \((1,-1)\) that stay on or above the axis.
Take sources \((-2i,0)\) and sinks \((2j,0)\). There is only one non-intersecting system.
Exercise 3.4.2 Pure
Show that the number of plane partitions in a \(1\times b\times c\) box is \(\binom{b+c}b\), both directly and from Theorem 3.4.6.
Exercise 3.4.3 Code
Compute the number of plane partitions in a \(4\times4\times4\) box.
Exercise 3.4.4 Math Olympiad
A regular hexagon with side \(2\) is cut into \(24\) unit equilateral triangles. In how many ways can it be tiled by rhombi made of two such triangles?
The tilings correspond to plane partitions in a \(2\times2\times2\) box.
Exercise 3.4.5 Pure Code
Count the pairs of non-intersecting lattice paths from \(A_1=(0,1)\) and \(A_2=(1,0)\) to \(B_1=(4,5)\) and \(B_2=(5,4)\), first with Theorem 3.4.2 and then by brute force. Which plane partitions do they correspond to?
\(e(A_1,B_1)=e(A_2,B_2)=\binom84\) and \(e(A_1,B_2)=e(A_2,B_1)=\binom85=\binom83\).
In Section 2.6 we met the permanent: the number of perfect matchings of a bipartite graph is \(\mathrm{per}(A)\), a determinant without signs, and Ryser’s formula computes it with about \(2^n\) terms instead of \(n!\). No essentially better method is expected. Yet for planar graphs, a clever choice of signs turns the count into a determinant. This is how physicists counted the domino tilings of a chessboard in 1961.
Leslie Valiant (born 1949)
British computer scientist. In 1979 he introduced the class #P of counting problems and proved that computing the permanent of a \(0/1\) matrix is #P-complete, although deciding whether it is nonzero is easy. He received the Turing Award in 2010.
So counting perfect matchings of bipartite graphs is as hard as any counting problem whose objects can be checked quickly. Determinants, by contrast, cost \(O(n^3)\). The question is when a permanent can be disguised as a determinant.
Definition 3.5.1. Let \(M=(m_{ij})\) be a skew-symmetric matrix of even order \(2n\). Its Pfaffian is \[\operatorname{Pf}(M)=\sum_{\mu}\operatorname{sign}(\mu)\prod_{\{i,j\}\in\mu,\ i<j}m_{ij},\] the sum running over the perfect matchings \(\mu\) of \(K_{2n}\), where \(\operatorname{sign}(\mu)\) is the sign of the permutation \(i_1j_1i_2j_2\cdots i_nj_n\) obtained by listing the pairs \(\{i_r<j_r\}\) in any order.
For \(2n=4\), \(\operatorname{Pf}(M)=m_{12}m_{34}-m_{13}m_{24}+m_{14}m_{23}\). The fundamental fact, due to Cayley, is that \(\operatorname{Pf}(M)^2=\det M\); so a Pfaffian can be computed as fast as a determinant, up to its sign.
Now orient the edges of a graph \(G\) on \([2n]\), and let \(M\) have \(m_{ij}=1\) and \(m_{ji}=-1\) when the edge \(ij\) is oriented from \(i\) to \(j\), and \(0\) when \(ij\) is not an edge. The nonzero terms of \(\operatorname{Pf}(M)\) are then the perfect matchings of \(G\), each with a sign \(\pm1\). If all the signs agree, the orientation is called Pfaffian, and then \[\#\{\text{perfect matchings of }G\}=|\operatorname{Pf}(M)|=\sqrt{\det M}.\]
Pieter Kasteleyn (1924–1996)
Dutch physicist. In 1961 he counted the domino tilings of a rectangle, the dimer problem of statistical mechanics, and in 1963 he proved that every planar graph has a Pfaffian orientation.
Theorem 3.5.2 (Kasteleyn). Let \(G\) be a plane graph, and orient its edges so that every bounded face has an odd number of edges oriented clockwise around it. Then the orientation is Pfaffian. Such an orientation always exists.
Proof. Sketch. Existence: start from any orientation of a spanning tree \(T\) of \(G\). The edges not in \(T\) form a spanning tree of the dual graph. Root it at the outer face and treat the bounded faces from the leaves inwards: each time choose a face with only one edge still unoriented, and orient that edge to make the face odd.
Pfaffian: two perfect matchings \(\mu,\mu'\) have a symmetric difference made of even cycles, and the ratio of their signs is a product over these cycles \(C\) of \((-1)^{c(C)+1}\), where \(c(C)\) is the number of edges of \(C\) oriented clockwise. Adding up the face conditions over the faces inside \(C\) and using Euler’s formula shows that \(c(C)\equiv v(C)+1\pmod 2\), where \(v(C)\) is the number of vertices inside \(C\). But \(v(C)\) is even, because the vertices inside \(C\) are matched among themselves by \(\mu\). So every cycle contributes \(+1\). A complete proof is in Lovász and Plummer, Matching Theory, Chapter 8.
The algorithm that finds a Kasteleyn orientation and evaluates the Pfaffian is called the FKT algorithm, after Fisher, Kasteleyn and Temperley. It counts the perfect matchings of any planar graph in polynomial time, and it is one of the few non-trivial #P problems known to become easy on a natural class of inputs.
A tiling of an \(m\times n\) rectangle by \(1\times2\) dominoes is a perfect matching of the grid \(P_m\,\square\,P_n\): each domino covers two adjacent squares.
Figure 3.5.3. The five domino tilings of a \(2\times4\) rectangle; vertical dominoes are shaded.
Theorem 3.5.4 (Temperley–Fisher, Kasteleyn, 1961). The number of domino tilings of an \(m\times n\) rectangle is \[\prod_{j=1}^{\lceil m/2\rceil}\prod_{k=1}^{\lceil n/2\rceil}\left(4\cos^2\frac{\pi j}{m+1}+4\cos^2\frac{\pi k}{n+1}\right).\]
Proof. Sketch. Orient the horizontal edges of the grid from left to right and the vertical edges alternately up and down from one column to the next; every unit square then has exactly one or three clockwise edges, so the orientation is Kasteleyn and the count is \(\sqrt{\det M}\). The matrix \(M\) is a sum of two commuting pieces, one for each direction, built from the matrix of a path, whose eigenvalues are \(2\cos(\pi j/(m+1))\). So the eigenvalues of \(M\) are of the form \(2\cos\frac{\pi j}{m+1}\pm2i\cos\frac{\pi k}{n+1}\), and grouping them in conjugate pairs gives the product.
The formula gives \(F_{n+1}\) for a \(2\times n\) strip, \(36\) for the \(4\times4\) square (the exercise of Section 2.6), \(6728\) for \(6\times6\), and \(12\,988\,816\) for the chessboard. The number of tilings of an \(n\times n\) square grows like \(e^{(G/\pi)n^2}\approx1.3385^{n^2}\), where \(G=1-\frac19+\frac1{25}-\cdots\) is Catalan’s constant; this is the kind of answer studied in Chapter 6.
import numpy as np
import networkx as nx
from math import cos, pi, prod
def tilings_formula(m, n):
r = 1.0
for j in range(1, m + 1):
for k in range(1, n + 1):
r *= 4 * cos(pi * j / (m + 1)) ** 2 + 4 * cos(pi * k / (n + 1)) ** 2
return round(r ** 0.25)
def tilings_kasteleyn(m, n):
# bipartite Kasteleyn matrix: weight 1 on horizontal edges, i on vertical edges
black = [(x, y) for x in range(n) for y in range(m) if (x + y) % 2 == 0]
white = [(x, y) for x in range(n) for y in range(m) if (x + y) % 2 == 1]
if len(black) != len(white):
return 0
w = {c: i for i, c in enumerate(white)}
K = np.zeros((len(black), len(white)), dtype=complex)
for i, (x, y) in enumerate(black):
for dx, dy, wt in ((1, 0, 1), (-1, 0, 1), (0, 1, 1j), (0, -1, 1j)):
if (x + dx, y + dy) in w:
K[i, w[(x + dx, y + dy)]] = wt
return round(abs(np.linalg.det(K)))
def tilings_brute(m, n):
G = nx.grid_2d_graph(m, n)
def rec(free):
if not free: return 1
v = min(free)
return sum(rec(free - {v, u}) for u in G[v] if u in free)
return rec(frozenset(G))
for m, n in [(2, 8), (3, 4), (4, 4), (5, 6), (6, 6), (8, 8)]:
b = tilings_brute(m, n) if m * n <= 36 else "-"
print(f"{m}x{n}: formula {tilings_formula(m, n)}, Kasteleyn {tilings_kasteleyn(m, n)}, brute {b}")
Lab · Domino tiling sampler
The reader chooses \(m\) and \(n\); the lab shows the count from Theorem 3.5.4 and draws uniformly random tilings by a Markov chain that rotates \(2\times2\) blocks. For large even squares the famous arctic circle appears.
This lab is being built for the web edition.
Research thread · Counting perfect matchings approximately
For bipartite graphs, Jerrum, Sinclair and Vigoda (2004) found a randomised algorithm that approximates the permanent of any non-negative matrix, to any fixed relative accuracy, in polynomial time. For non-bipartite graphs no such algorithm is known: approximating the number of perfect matchings of a general graph is open. Read the introduction of their paper and find out what goes wrong for non-bipartite graphs.
Reading: M. Jerrum, A. Sinclair and E. Vigoda, A polynomial-time approximation algorithm for the permanent of a matrix with nonnegative entries, J. ACM 51 (2004); L. Lovász and M. D. Plummer, Matching Theory, Chapter 8.
Exercise 3.5.1 Pure
Show directly that a \(2\times n\) rectangle has \(F_{n+1}\) domino tilings, and check it against Figure 3.5.3.
Exercise 3.5.2 Pure Math Olympiad
Let \(a_n\) be the number of domino tilings of a \(3\times2n\) rectangle. Show that \(a_1=3\), \(a_2=11\) and \(a_n=4a_{n-1}-a_{n-2}\) for \(n\geqslant3\).
Cut the rectangle at the first vertical line, other than the left edge, that no domino crosses.
Set \(a_0=1\); then \(a_n=3a_{n-1}+2(a_{n-2}+a_{n-3}+\cdots+a_0)\).
Exercise 3.5.3 Math Olympiad
Two opposite corner squares are removed from an \(8\times8\) chessboard. Show that the remaining \(62\) squares cannot be tiled by dominoes.
Every domino covers one black and one white square.
Exercise 3.5.4 Pure
Verify the formula \(\operatorname{Pf}(M)^2=\det M\) for a general skew-symmetric \(4\times4\) matrix.
Exercise 3.5.5 Code
Use the Kasteleyn matrix of this section to compute the number of domino tilings of a \(10\times10\) square.
Exercise 3.5.6 Pure
The Petersen graph has \(6\) perfect matchings. Find them, and show that any two of them share exactly one edge.
Draw the graph as an outer \(5\)-cycle, an inner pentagram and five spokes. A perfect matching uses an odd number of spokes; show that it uses exactly one or all five.
Exercise 3.5.7 Computer Science Algorithm
Ryser’s formula evaluates an \(n\times n\) permanent with \(O(2^nn)\) operations. Estimate the largest \(n\) for which this is practical on a laptop, and compare with the size of planar graphs that FKT handles in a second.
Exercise 3.5.8 Research Project
A project: graphs without a Pfaffian orientation.
For 2, restricting the orientation keeps the signs of a subset of the same perfect matchings.
For 3, the famous example is the Heawood graph, the incidence graph of the Fano plane; see Robertson, Seymour and Thomas, Permanents, Pfaffian orientations, and even directed circuits (1999).
Part B is about counting up to symmetry. How many graphs on \(5\) vertices are there if we do not care about the names of the vertices? How many ways are there to colour the corners of a cube, if two colourings that differ by a rotation count as one? Both questions ask for the number of orbits of a group acting on a finite set, and this section sets up the language.
Definition 3.6.1. A group action of a group \(\Gamma\) on a set \(X\) assigns to every \(\gamma\in\Gamma\) a bijection \(x\mapsto\gamma x\) of \(X\) such that \(1x=x\) and \(\gamma(\delta x)=(\gamma\delta)x\). The orbit of \(x\) is \(\Gamma x=\{\gamma x:\gamma\in\Gamma\}\), and the stabiliser of \(x\) is \(\Gamma_x=\{\gamma:\gamma x=x\}\), a subgroup of \(\Gamma\).
Two elements are in the same orbit if one is carried to the other by some \(\gamma\); this is an equivalence relation, so the orbits partition \(X\).
Theorem 3.6.2 (Orbit–stabiliser). For every \(x\in X\), \(|\Gamma x|\cdot|\Gamma_x|=|\Gamma|\).
Proof. \(\gamma x=\delta x\) holds exactly when \(\delta^{-1}\gamma\in\Gamma_x\), that is, when \(\gamma\) lies in the coset \(\delta\Gamma_x\). So the map \(\gamma\mapsto\gamma x\) is constant on the cosets of \(\Gamma_x\) and takes different values on different cosets. There are \(|\Gamma|/|\Gamma_x|\) cosets.
The symmetric group \(S_n\) acts on the \(2^{\binom n2}\) graphs on \([n]\): \(\sigma\) sends \(G\) to the graph with edges \(\sigma(u)\sigma(v)\). The orbits are the isomorphism classes, the unlabeled graphs, and the stabiliser of \(G\) is \(\mathrm{Aut}(G)\). So Theorem 3.6.2 is Theorem 1.3.3: \(G\) has \(n!/|\mathrm{Aut}(G)|\) labeled copies.
\(\mathrm{Aut}(G)\) acts on \(V(G)\), on \(E(G)\), and on the colourings \(c:V(G)\to[k]\) by \((\gamma c)(v)=c(\gamma^{-1}v)\). Its orbits on colourings are the colourings up to symmetry.
The cyclic group \(\mathbb Z_n\) of rotations, or the dihedral group \(D_n\) of rotations and reflections, acts on the words of length \(n\) written around a circle. The orbits are necklaces and bracelets.
Proposition 3.6.3. (a) \(|\mathrm{Aut}(K_n)|=n!\), \(|\mathrm{Aut}(C_n)|=2n\) for \(n\geqslant3\), and \(|\mathrm{Aut}(K_{m,n})|=m!\,n!\) for \(m\neq n\), \(2(n!)^2\) for \(m=n\).
\(|\mathrm{Aut}(Q_n)|=2^n\,n!\).
The automorphism group of the Petersen graph is isomorphic to \(S_5\), of order \(120\).
Proof. (a) is a direct check.
The maps \(w\mapsto w\oplus s\) (add a fixed word modulo \(2\)) and the \(n!\) permutations of the coordinates are automorphisms; so \(Q_n\) is vertex-transitive, and by Theorem 3.6.2 it suffices to show that the stabiliser of \(0\cdots0\) has order \(n!\). Let \(\varphi\) fix \(0\cdots0\). It permutes the neighbours \(e_1,\ldots,e_n\) of \(0\cdots0\), say \(\varphi(e_i)=e_{\pi(i)}\), and composing with the coordinate permutation \(\pi^{-1}\) we may assume that \(\varphi\) fixes every \(e_i\). Then \(\varphi\) fixes every word \(w\), by induction on the number \(j\) of ones in \(w\): for \(j\geqslant2\), \(w\) is the only vertex at distance \(j\) from \(0\cdots0\) adjacent to the words obtained from \(w\) by deleting one of its ones, and these are fixed by induction.
Label the vertices of the Petersen graph by the \(2\)-subsets of \([5]\), two being adjacent when disjoint. Every permutation of \([5]\) gives an automorphism, so \(|\mathrm{Aut}|\geqslant120\). The graph is vertex-transitive, and the stabiliser of the vertex \(\{1,2\}\) permutes its three neighbours \(\{3,4\},\{3,5\},\{4,5\}\); one checks that an automorphism fixing \(\{1,2\}\) and each of its neighbours is either the identity or the transposition \((12)\), so the stabiliser has order at most \(3!\cdot2=12\) and \(|\mathrm{Aut}|\leqslant10\cdot12=120\).
Example 3.6.4. The Petersen graph has \(10!/120=30\,240\) labeled copies on \([10]\), and \(Q_3\) has \(8!/48=840\) labeled copies on \([8]\).
Robert Frucht (1906–1997)
Born in Brno and raised in Berlin, he worked as an actuary in Trieste and emigrated to Chile in 1939. In 1939 he proved that every finite group is the automorphism group of some graph, and in 1949 he found the cubic graph on \(12\) vertices with no symmetry at all, now called the Frucht graph.
Theorem 3.6.5 (Frucht, 1939). For every finite group \(\Gamma\) there is a graph \(G\) with \(\mathrm{Aut}(G)\cong\Gamma\).
A graph with \(|\mathrm{Aut}(G)|=1\) is called asymmetric. Small graphs are rarely asymmetric: there are none on \(2\) to \(5\) vertices, \(8\) on \(6\) vertices and \(152\) on \(7\). Large graphs almost always are: Erdős and Rényi proved in 1963 that the proportion of asymmetric graphs on \([n]\) tends to \(1\). We return to this in Chapter 6 and to asymmetric colourings in Section 3.10.
import itertools as it
import networkx as nx
from networkx.algorithms.isomorphism import GraphMatcher
from math import factorial, comb
def aut_order(G):
return sum(1 for _ in GraphMatcher(G, G).isomorphisms_iter())
for name, G in [("K_5", nx.complete_graph(5)), ("C_7", nx.cycle_graph(7)), ("K_3,3", nx.complete_bipartite_graph(3, 3)),
("Q_3", nx.hypercube_graph(3)), ("Q_4", nx.hypercube_graph(4)), ("Petersen", nx.petersen_graph())]:
a = aut_order(G); n = G.number_of_nodes()
print(f"{name:9s} |Aut| = {a:5d} labeled copies = {factorial(n) // a}")
# the orbit-counting check of Chapter 1: sum over unlabeled graphs of n!/|Aut| = 2^C(n,2)
from networkx.generators.atlas import graph_atlas_g
for n in range(1, 7):
types = [G for G in graph_atlas_g() if G.number_of_nodes() == n]
total = sum(factorial(n) // aut_order(G) for G in types)
asym = sum(1 for G in types if aut_order(G) == 1)
print(n, len(types), "types,", total, "= 2^C(n,2) =", 2 ** comb(n, 2), "; asymmetric:", asym)
Exercise 3.6.1 Pure
Show that \(\mathrm{Aut}(G)=\mathrm{Aut}(\overline G)\).
Exercise 3.6.2 Pure
Compute \(|\mathrm{Aut}(W_n)|\) for \(n\geqslant4\), and explain why \(W_3\) is different.
For \(n\geqslant4\) the centre is the only vertex of degree \(n\).
Exercise 3.6.3 Pure
How many labeled copies of \(K_{3,3}\) are there on \([6]\)? Check the answer by choosing the bipartition directly.
Exercise 3.6.4 Pure Math Olympiad
Find a tree with at least two vertices and no non-trivial automorphism, with as few vertices as possible.
A path has its reversal; a tree with a vertex of degree \(3\) needs its three branches to have different shapes.
Exercise 3.6.5 Code
Verify by computer that there are exactly \(8\) asymmetric graphs on \(6\) vertices, and draw them. How are they related under complementation?
Exercise 3.6.6 Pure
Let \(\Gamma\) act on \(X\). Show that if \(x\) and \(y\) lie in the same orbit, then their stabilisers are conjugate: \(\Gamma_y=\gamma\Gamma_x\gamma^{-1}\) for some \(\gamma\).
To count orbits we could list them, but listing is exactly what we want to avoid. The lemma of this section counts orbits by counting fixed points, which is usually easy.
Theorem 3.7.1 (Burnside’s lemma). If a finite group \(\Gamma\) acts on a finite set \(X\), the number of orbits is \[\frac1{|\Gamma|}\sum_{\gamma\in\Gamma}|\mathrm{Fix}(\gamma)|,\qquad \mathrm{Fix}(\gamma)=\{x\in X:\gamma x=x\}.\]
Proof. Count the pairs \((\gamma,x)\) with \(\gamma x=x\) in two ways, as in Section 2.2. By \(\gamma\) we get \(\sum_\gamma|\mathrm{Fix}(\gamma)|\). By \(x\) we get \(\sum_x|\Gamma_x|=\sum_x|\Gamma|/|\Gamma x|\), by Theorem 3.6.2. Each orbit \(O\) contributes \(|O|\cdot|\Gamma|/|O|=|\Gamma|\) to the last sum.
William Burnside (1852–1927)
British mathematician, for many years professor at the Royal Naval College in Greenwich. His Theory of Groups of Finite Order (1897) was the first group theory book in English.
Burnside’s lemma is not Burnside’s. He gave it in his 1897 book with a credit to Frobenius (1887), and Cauchy had used it in 1845. Peter Neumann wrote a paper in 1979 called A lemma that is not Burnside’s; the name Cauchy–Frobenius lemma is also used, and some authors call it simply the orbit-counting lemma.
A necklace of length \(n\) with \(k\) colours is an orbit of the rotation group \(\mathbb Z_n\) on the \(k^n\) words; a bracelet is an orbit of the dihedral group \(D_n\), which also allows turning the necklace over.
Figure 3.7.2. The six binary necklaces of length \(4\).
Theorem 3.7.3. The number of necklaces of length \(n\) with \(k\) colours is \[N(n,k)=\frac1n\sum_{d\mid n}\varphi(d)\,k^{n/d},\] where \(\varphi\) is Euler’s function. The number of bracelets is \(\frac12\big(N(n,k)+k^{(n+1)/2}\big)\) for odd \(n\) and \(\frac12\big(N(n,k)+\frac{k+1}2k^{n/2}\big)\) for even \(n\).
Proof. The rotation by \(j\) places splits the \(n\) positions into \(\gcd(n,j)\) cycles, and a word is fixed exactly when it is constant on each cycle; so it fixes \(k^{\gcd(n,j)}\) words. For each \(d\mid n\) there are \(\varphi(d)\) values of \(j\in\{0,\ldots,n-1\}\) with \(\gcd(n,j)=n/d\), and Theorem 3.7.1 gives \(N(n,k)\).
For bracelets add the \(n\) reflections. If \(n\) is odd, each fixes one position and pairs up the rest, fixing \(k^{(n+1)/2}\) words. If \(n\) is even, half of them fix two positions (\(k^{n/2+1}\) fixed words) and half fix none (\(k^{n/2}\)). Divide the total by \(|D_n|=2n\).
For \(k=2\) the necklaces of lengths \(1,\ldots,8\) number \(2,3,4,6,8,14,20,36\) and the bracelets \(2,3,4,6,8,13,18,30\). In Figure 3.7.2 the six necklaces of length \(4\) are also the six bracelets: turning over a necklace of length \(4\) never gives anything new.
Corollary 3.7.4. The number of colourings \(V(G)\to[k]\) up to the automorphisms of \(G\) is \[\frac1{|\mathrm{Aut}(G)|}\sum_{\gamma\in\mathrm{Aut}(G)}k^{c(\gamma)},\] where \(c(\gamma)\) is the number of cycles of \(\gamma\) as a permutation of \(V(G)\).
Proof. A colouring is fixed by \(\gamma\) exactly when it is constant on the cycles of \(\gamma\).
Example 3.7.5. The automorphism group of \(Q_3\) has order \(48\). Grouping its elements by their cycle types on the \(8\) vertices, Corollary 3.7.4 gives \(22\) colourings of the corners of a cube with two colours. If only the \(24\) rotations of the solid cube are allowed, two colourings that are mirror images become different, and the count rises to \(23\). With three colours the numbers are \(267\) and \(333\).
Remark 3.7.6. The Petersen graph has \(34\) two-colourings up to symmetry, which is also the number of unlabeled graphs on \(5\) vertices. This is no coincidence: the vertices of the Petersen graph are the \(2\)-subsets of \([5]\), a red-blue colouring is a graph on \([5]\) (red pairs are edges), and the automorphisms are the permutations of \([5]\), by Proposition 3.6.3. So the question how many graphs are there on \(5\) vertices? is itself a question about colourings up to symmetry. Section 3.8 builds on this idea.
The same method counts proper colourings up to symmetry, but now \(\mathrm{Fix}(\gamma)\) is the set of proper colourings that are constant on the cycles of \(\gamma\); it is empty as soon as some cycle of \(\gamma\) contains both ends of an edge. For \(C_5\) with \(3\) colours, only the identity fixes a proper colouring, so the \(P(C_5,3)=30\) proper colourings fall into \(30/10=3\) classes.
import itertools as it
import networkx as nx
from networkx.algorithms.isomorphism import GraphMatcher
from math import gcd
def automorphisms(G):
return list(GraphMatcher(G, G).isomorphisms_iter())
def n_cycles(perm):
seen, c = set(), 0
for v in perm:
if v not in seen:
c += 1
while v not in seen:
seen.add(v); v = perm[v]
return c
def colourings_up_to_symmetry(G, k):
A = automorphisms(G)
return sum(k ** n_cycles(a) for a in A) // len(A)
def proper_up_to_symmetry(G, k):
A, V = automorphisms(G), list(G)
total = 0
for a in A:
for col in it.product(range(k), repeat=len(V)):
c = dict(zip(V, col))
if all(c[u] != c[v] for u, v in G.edges()) and all(c[a[v]] == c[v] for v in V):
total += 1
return total // len(A)
def necklaces(n, k):
return sum(k ** gcd(n, j) for j in range(n)) // n
print("necklaces, k = 2:", [necklaces(n, 2) for n in range(1, 11)])
for name, G in [("C_6", nx.cycle_graph(6)), ("Q_3", nx.hypercube_graph(3)), ("Petersen", nx.petersen_graph())]:
print(name, [colourings_up_to_symmetry(G, k) for k in (2, 3, 4)])
print("proper 3-colourings up to symmetry: C_5", proper_up_to_symmetry(nx.cycle_graph(5), 3),
" Petersen", proper_up_to_symmetry(nx.petersen_graph(), 3))
Exercise 3.7.1 Pure
How many necklaces with \(6\) beads can be made from beads of \(3\) colours?
Exercise 3.7.2 Pure
How many binary bracelets of length \(8\) are there?
Exercise 3.7.3 Math Olympiad
The six faces of a cube are painted, each with one of three colours. How many different cubes can be obtained, if two cubes are the same when one can be rotated into the other?
The \(24\) rotations are: the identity; \(6\) quarter turns and \(3\) half turns about axes through opposite faces; \(6\) half turns about axes through midpoints of opposite edges; \(8\) turns by \(120^\circ\) about diagonals. Count the cycles of each on the faces.
Exercise 3.7.4 Pure
Show that \(\frac1n\sum_{d\mid n}\varphi(d)k^{n/d}\) is an integer for all positive integers \(n,k\). Deduce Fermat’s little theorem \(k^p\equiv k\pmod p\).
The formula counts something.
For \(n=p\) prime the formula reads \(\frac1p\big(k^p+(p-1)k\big)\).
Exercise 3.7.5 Pure Code
How many proper \(3\)-colourings does the Petersen graph have, and how many are there up to its automorphisms?
The Petersen graph has \(120\) proper \(3\)-colourings; they are not permuted freely by the \(120\) automorphisms.
Exercise 3.7.6 Pure
Show that the number of ways to label the vertices of \(G\) with \(1,\ldots,n\), up to the automorphisms of \(G\), is \(n!/|\mathrm{Aut}(G)|\), and explain the connection with Theorem 1.3.3.
Exercise 3.7.7 Computer Science Algorithm
Design an algorithm that lists one representative of each necklace of length \(n\) over \(k\) letters with constant time per necklace on average. (Search for Lyndon words and the algorithm of Fredricksen, Kessler and Maiorana.)
Burnside’s lemma counts all the orbits at once. Often we want more: how many unlabeled graphs on \(6\) vertices have exactly \(7\) edges? Pólya’s theorem keeps track of such weights by replacing the number \(k^{c(\gamma)}\) with a polynomial that remembers the lengths of the cycles.
Definition 3.8.1. Let \(\Gamma\) act on a set \(X\) of size \(m\). For \(\gamma\in\Gamma\) let \(c_i(\gamma)\) be the number of cycles of length \(i\) of \(\gamma\) on \(X\). The cycle index is the polynomial \[Z(\Gamma;x_1,\ldots,x_m)=\frac1{|\Gamma|}\sum_{\gamma\in\Gamma}x_1^{c_1(\gamma)}x_2^{c_2(\gamma)}\cdots x_m^{c_m(\gamma)}.\]
Theorem 3.8.2 (Pólya, 1937). Suppose each colour in a set \(Y\) of colours has a weight, and let \(f(t)=\sum_{y\in Y}t^{w(y)}\). Give a colouring \(X\to Y\) the weight \(\sum_xw(c(x))\). Then the number of orbits of colourings of weight \(j\) is the coefficient of \(t^j\) in \[Z\big(\Gamma;f(t),f(t^2),\ldots,f(t^m)\big).\]
Proof. Apply Theorem 3.7.1 to the colourings of weight \(j\) only; \(\Gamma\) preserves weights, so it acts on them. A colouring fixed by \(\gamma\) is constant on each cycle, and a cycle of length \(i\) coloured \(y\) contributes \(i\,w(y)\) to the weight. So the colourings fixed by \(\gamma\) are counted, by weight, by \(\prod_if(t^i)^{c_i(\gamma)}\). Average over \(\gamma\).
George Pólya (1887–1985)
Hungarian-born mathematician, at ETH Zürich and later at Stanford. His 1937 paper on counting chemical compounds, graphs and trees up to symmetry founded the subject of this part of the chapter. His How to Solve It (1945) is still read by students preparing for olympiads.
If you can’t solve a problem, then there is an easier problem you can solve: find it.
— How to Solve It, 1945 (as usually quoted)
J. Howard Redfield had published the same method in 1927 in the American Journal of Mathematics, but the paper went unnoticed until Frank Harary drew attention to it in 1960.
An unlabeled graph on \(n\) vertices is an orbit of \(S_n\) acting on the red-blue colourings of the \(\binom n2\) pairs, where red means edge. So we need the cycle index of the pair group \(S_n^{(2)}\): the action of \(S_n\) on pairs.
Lemma 3.8.3. Let \(\sigma\in S_n\) have cycles of lengths \(\ell_1,\ldots,\ell_r\) on \([n]\). Then on the pairs:
two vertices in the same cycle of length \(\ell\) give \(\lfloor(\ell-1)/2\rfloor\) cycles of length \(\ell\), plus one cycle of length \(\ell/2\) if \(\ell\) is even;
two vertices in different cycles of lengths \(\ell_a,\ell_b\) give \(\gcd(\ell_a,\ell_b)\) cycles of length \(\operatorname{lcm}(\ell_a,\ell_b)\).
Proof. (a) Number the cycle \(0,\ldots,\ell-1\); \(\sigma\) adds \(1\) modulo \(\ell\). The pair \(\{u,v\}\) is determined up to rotation by its “distance” \(\min(v-u,u-v)\bmod\ell\), which takes the values \(1,\ldots,\lfloor\ell/2\rfloor\). Each value gives one cycle of length \(\ell\), except the value \(\ell/2\) for even \(\ell\), whose cycle has length \(\ell/2\).
Example 3.8.4. For \(n=4\): the identity gives \(x_1^6\); the \(6\) transpositions and the \(3\) double transpositions give \(x_1^2x_2^2\); the \(8\) three-cycles give \(x_3^2\); the \(6\) four-cycles give \(x_2x_4\). So \[Z(S_4^{(2)})=\tfrac1{24}\big(x_1^6+9x_1^2x_2^2+8x_3^2+6x_2x_4\big).\] Substituting \(x_i=1+t^i\) (colour non-edge has weight \(0\), edge weight \(1\)) gives \[1+t+2t^2+3t^3+2t^4+t^5+t^6,\] the unlabeled graphs on \(4\) vertices counted by edges; there are \(11\) in all.
Theorem 3.8.5. The number of unlabeled graphs on \(n\) vertices with \(j\) edges is the coefficient of \(t^j\) in \(Z\big(S_n^{(2)};1+t,1+t^2,\ldots\big)\). The total number \(g_n\) is \(Z(S_n^{(2)};2,2,\ldots,2)\): \[g_1,g_2,\ldots,g_{10}=1,\ 2,\ 4,\ 11,\ 34,\ 156,\ 1044,\ 12346,\ 274668,\ 12005168.\]
Since \(Z\) depends on \(\sigma\) only through its cycle type, the sum runs over the partitions of \(n\), weighted by the class sizes \(n!/\prod_ii^{m_i}m_i!\). For \(n=10\) that is \(42\) terms instead of \(10!\). The same method counts multigraphs with edge multiplicities at most \(k\) (substitute \(x_i=k+1\)), digraphs (use the action of \(S_n\) on ordered pairs: \(1,3,16,218,9608\) for \(n\leqslant5\)), and graphs with any other kind of decoration on the pairs.
from math import factorial, gcd, prod
from sympy import symbols, expand, Poly
from sympy.utilities.iterables import partitions
def pair_cycle_lengths(lens):
out = []
for i, a in enumerate(lens):
out += [a] * ((a - 1) // 2) + ([a // 2] if a % 2 == 0 else [])
for b in lens[i + 1:]:
out += [a * b // gcd(a, b)] * gcd(a, b)
return out
def classes(n):
for p in partitions(n):
lens = [l for l, m in p.items() for _ in range(m)]
yield lens, factorial(n) // prod(l ** m * factorial(m) for l, m in p.items())
def unlabeled_graphs(n):
return sum(size * 2 ** len(pair_cycle_lengths(l)) for l, size in classes(n)) // factorial(n)
t = symbols("t")
def by_edges(n):
Z = sum(size * prod(1 + t ** c for c in pair_cycle_lengths(l)) for l, size in classes(n))
return Poly(expand(Z / factorial(n)), t).all_coeffs()[::-1]
print("g_n:", [unlabeled_graphs(n) for n in range(1, 13)])
print("n = 6 by edges:", by_edges(6))
print("multigraphs, multiplicity <= 2:", [sum(s * 3 ** len(pair_cycle_lengths(l)) for l, s in classes(n)) // factorial(n) for n in range(1, 7)])
Exercise 3.8.1 Pure
Compute \(Z(S_3^{(2)})\) and use it to list the unlabeled graphs on \(3\) vertices by number of edges.
Exercise 3.8.2 Pure
How many unlabeled graphs on \(5\) vertices have exactly \(5\) edges? Draw them.
Exercise 3.8.3 Code
How many unlabeled graphs on \(6\) vertices have exactly \(7\) edges?
Exercise 3.8.4 Pure
Explain why the coefficients of \(Z(S_n^{(2)};1+t,1+t^2,\ldots)\) are symmetric: the coefficient of \(t^j\) equals that of \(t^{\binom n2-j}\).
Complementation.
Exercise 3.8.5 Pure Code
How many unlabeled multigraphs on \(4\) vertices are there in which two vertices are joined by at most \(2\) edges?
Exercise 3.8.6 Code
Compute the ratio \(g_n\cdot n!\big/2^{\binom n2}\) for \(n\leqslant12\) with the program of this section. What do you guess about its limit? (A proof comes in Chapter 6.)
The identity contributes \(2^{\binom n2}/n!\) to \(g_n\); every other permutation fixes far fewer graphs.
Exercise 3.8.7 Research Project
A project: counting unlabeled trees with Pólya. Let \(r_n\) be the number of unlabeled rooted trees on \(n\) vertices, and \(R(t)=\sum r_nt^n\).
In Section 3.8 the group moved the positions (the pairs of vertices) and left the colours alone. Some questions also let the colours move. Counting graphs up to complementation means that swapping edge and non-edge is allowed as well as renaming the vertices. De Bruijn’s theorem handles both kinds of symmetry at once.
Theorem 3.9.1 (de Bruijn, 1959). Let \(\Gamma\) act on a finite set \(X\) and \(\Delta\) act on a finite set \(Y\). The group \(\Gamma\times\Delta\) acts on the maps \(f:X\to Y\) by \(\big((\gamma,\delta)f\big)(x)=\delta\big(f(\gamma^{-1}x)\big)\), and the number of orbits is \[\frac1{|\Gamma|\,|\Delta|}\sum_{\gamma\in\Gamma}\sum_{\delta\in\Delta}\ \prod_{i\geqslant1}\Big(\sum_{d\mid i}d\,c_d(\delta)\Big)^{c_i(\gamma)},\] where \(c_i(\gamma)\) and \(c_d(\delta)\) count the cycles of length \(i\) of \(\gamma\) on \(X\) and of length \(d\) of \(\delta\) on \(Y\).
Proof. By Theorem 3.7.1 we must count the maps fixed by \((\gamma,\delta)\), that is, with \(f(\gamma x)=\delta f(x)\) for all \(x\). On a cycle \(x,\gamma x,\ldots,\gamma^{i-1}x\) of \(\gamma\), such an \(f\) is determined by \(y=f(x)\), and it is consistent exactly when \(\delta^iy=y\), that is, when \(y\) lies on a cycle of \(\delta\) whose length \(d\) divides \(i\). There are \(\sum_{d\mid i}d\,c_d(\delta)\) such \(y\), and the cycles of \(\gamma\) are independent.
De Bruijn, whom we met in Section 2.8, published this theorem in 1959. He also created Automath (1967), the first computer system for checking mathematical proofs.
A graph is self-complementary if \(G\cong\overline G\). The path \(P_4\) is one, and so are \(C_5\) and the bull (a triangle with two pendant edges at different vertices). Let \(\mathrm{sc}_n\) be the number of unlabeled self-complementary graphs on \(n\) vertices.
Lemma 3.9.2. All cycles of \(\sigma\in S_n\) on the pairs have even length if and only if all cycles of \(\sigma\) on \([n]\) have length divisible by \(4\), except for at most one fixed point.
Proof. By Lemma 3.8.3, a cycle of odd length \(\ell\geqslant3\) produces pair-cycles of length \(\ell\); two fixed points produce a fixed pair; a cycle of length \(\ell\equiv2\pmod4\) produces a pair-cycle of length \(\ell/2\), which is odd. Conversely, if all cycles have length divisible by \(4\) apart from at most one fixed point, every pair-cycle has length \(\ell\), \(\ell/2\) or \(\operatorname{lcm}(\ell_a,\ell_b)\), all even.
Theorem 3.9.3 (Read, 1963).
\[\mathrm{sc}_n=\frac1{n!}\sum_{\sigma}2^{c(\sigma)},\] where \(\sigma\) runs over the permutations described in Lemma 3.9.2 and \(c(\sigma)\) is the number of cycles of \(\sigma\) on the pairs. In particular \(\mathrm{sc}_n=0\) unless \(n\equiv0\) or \(1\pmod4\), and \[\mathrm{sc}_1,\ldots,\mathrm{sc}_{12}=1,0,0,1,2,0,0,10,36,0,0,720.\]
Proof. Let \(S_n\times\mathbb Z_2\) act on the red-blue colourings of the pairs, the non-trivial element of \(\mathbb Z_2\) swapping the two colours. Its orbits are the graphs up to isomorphism and complementation. Each orbit is either one self-complementary graph or a pair \(\{G,\overline G\}\) of non-self-complementary graphs, so the number of orbits is \(\frac12(g_n+\mathrm{sc}_n)\).
Now count with Theorem 3.9.1. The elements \((\sigma,1)\) contribute \(\sum_\sigma2^{c(\sigma)}=n!\,g_n\). The element \((\sigma,\text{swap})\) fixes a colouring when the colours alternate around every pair-cycle of \(\sigma\); this is possible only if all pair-cycles are even, and then there are \(2^{c(\sigma)}\) such colourings. So the number of orbits is \(\frac1{2\cdot n!}\big(n!\,g_n+\sum_\sigma2^{c(\sigma)}\big)\), with the second sum over the permutations of Lemma 3.9.2. Comparing the two expressions gives the formula. If \(n\equiv2,3\pmod4\), no such permutation exists.
Ronald C. Read (1924–2019)
British–Canadian mathematician at the University of Waterloo. He counted self-complementary graphs in 1963, and his work on computer enumeration of graphs helped turn graphical enumeration into a computational subject.
Frank Harary and Edgar Palmer collected the methods of Part B in their book Graphical Enumeration (1973), still the standard reference. Their tables were computed with exactly these cycle-index formulas.
A tournament on \([n]\) orients every pair, so there are \(2^{\binom n2}\) of them. Counting them up to isomorphism is a power-group problem in disguise: a permutation acts on the pairs and may reverse the orientation of a pair it maps to itself.
Theorem 3.9.4. The number of unlabeled tournaments on \(n\) vertices is \[\frac1{n!}\sum_\sigma2^{\,p(\sigma)},\qquad p(\sigma)=\sum_i\frac{\ell_i-1}2+\sum_{i<j}\gcd(\ell_i,\ell_j),\] where \(\sigma\) runs over the permutations all of whose cycles have odd length, and \(\ell_1,\ell_2,\ldots\) are those lengths. The values for \(n=1,\ldots,9\) are \(1,1,2,4,12,56,456,6880,191536\).
Proof. If \(\sigma\) has a cycle of even length \(\ell\), then \(\sigma^{\ell/2}\) swaps \(u\) and \(\sigma^{\ell/2}u\) for \(u\) on that cycle, so no tournament fixed by \(\sigma\) can orient this pair. If all cycles are odd, no power of \(\sigma\) swaps two vertices; then a fixed tournament is obtained by choosing freely the orientation of one pair in each pair-cycle, and \(p(\sigma)\) is the number of pair-cycles by Lemma 3.8.3. Apply Theorem 3.7.1.
from math import factorial, gcd, prod
from sympy.utilities.iterables import partitions
def classes(n):
for p in partitions(n):
lens = [l for l, m in p.items() for _ in range(m)]
yield lens, factorial(n) // prod(l ** m * factorial(m) for l, m in p.items())
def pair_cycle_lengths(lens):
out = []
for i, a in enumerate(lens):
out += [a] * ((a - 1) // 2) + ([a // 2] if a % 2 == 0 else [])
for b in lens[i + 1:]:
out += [a * b // gcd(a, b)] * gcd(a, b)
return out
def self_complementary(n):
tot = 0
for l, s in classes(n):
pc = pair_cycle_lengths(l)
if all(c % 2 == 0 for c in pc):
tot += s * 2 ** len(pc)
return tot // factorial(n)
def tournaments(n):
tot = 0
for l, s in classes(n):
if all(x % 2 == 1 for x in l):
p = sum((x - 1) // 2 for x in l) + sum(gcd(l[i], l[j]) for i in range(len(l)) for j in range(i + 1, len(l)))
tot += s * 2 ** p
return tot // factorial(n)
print("self-complementary:", [self_complementary(n) for n in range(1, 17)])
print("tournaments: ", [tournaments(n) for n in range(1, 12)])
Exercise 3.9.1 Pure
Show directly that a self-complementary graph on \(n\) vertices has \(\frac12\binom n2\) edges, and deduce that \(n\equiv0\) or \(1\pmod4\).
Exercise 3.9.2 Pure
Find the self-complementary graphs on \(4\) and \(5\) vertices, and check that there are \(1\) and \(2\) of them.
Exercise 3.9.3 Pure
Show that self-complementary graphs exist for every \(n\equiv0,1\pmod4\).
For \(n=4m\), take sets \(A,B,C,D\) of size \(m\); make \(B\) and \(C\) cliques and \(A\) and \(D\) independent, and join all of \(A\) to \(B\), \(B\) to \(C\), and \(C\) to \(D\). For \(m=1\) this is \(P_4\).
For \(n=4m+1\), add one vertex joined to all of \(B\cup C\).
Exercise 3.9.4 Pure
How many graphs on \(8\) vertices are there up to isomorphism and complementation?
Exercise 3.9.5 Pure
Use Theorem 3.9.4 to compute the number of unlabeled tournaments on \(5\) vertices by hand, and list the cycle types that contribute.
Exercise 3.9.6 Math Olympiad
Show that every tournament has a Hamiltonian path (a directed path through all vertices), and that a tournament on \(n\) vertices has at most one Hamiltonian path if and only if it is transitive.
Exercise 3.9.7 Research Project
A project: self-complementary digraphs and tournaments. A tournament is self-converse if it is isomorphic to the tournament obtained by reversing all arcs.
Now the element \((\sigma,\text{reverse})\) fixes a tournament when \(\sigma\) maps every arc \(uv\) to the arc \(\sigma(v)\sigma(u)\).
So far we have counted objects up to symmetry. The last section turns the question around: how many colours are needed to destroy all the symmetry of a graph? The question comes from a puzzle about keys on a ring: if the keys look alike, how many colours of key covers does one need to tell them apart, when the ring can be rotated and turned over?
Definition 3.10.1. A colouring \(c:V(G)\to[k]\), not necessarily proper, is distinguishing if the only automorphism \(\gamma\) of \(G\) with \(c(\gamma v)=c(v)\) for all \(v\) is the identity. The distinguishing number \(D(G)\) is the least \(k\) for which a distinguishing \(k\)-colouring exists.
Michael Albertson and Karen Collins introduced the distinguishing number in 1996; the key-ring puzzle had been posed by Frank Rubin in 1979. For a ring of \(n\) keys, the answer is \(D(C_n)\).
Proposition 3.10.2. (a) \(D(G)=1\) if and only if \(G\) is asymmetric.
\(D(K_n)=n\) and \(D(K_{1,n})=n\) for \(n\geqslant2\); \(D(P_n)=2\) for \(n\geqslant2\).
\(D(C_n)=3\) for \(n=3,4,5\), and \(D(C_n)=2\) for \(n\geqslant6\).
\(D(K_{n,n})=n+1\) for \(n\geqslant2\).
Proof. (a) and (b) are immediate: in \(K_n\) any two vertices of the same colour can be swapped, and so can two leaves of a star.
For \(n\geqslant6\) colour the vertices \(0,1,3\) red and the rest blue. A symmetry of the cycle preserving the red set preserves the gaps \(1,2,n-3\) between consecutive red vertices, which are distinct, so it is the identity. Three colours always suffice: give vertex \(0\) colour \(1\), vertex \(1\) colour \(2\) and all other vertices colour \(3\); an automorphism of a cycle that fixes two adjacent vertices is the identity. For \(n\leqslant5\) one checks the few red sets of size at most \(\lfloor n/2\rfloor\): each is preserved by a reflection.
Two vertices on the same side with the same colour can be swapped, so each side uses distinct colours. If only \(n\) colours are available, each side uses all of them, and matching the vertices of equal colour across the sides gives a colour-preserving automorphism. With \(n+1\) colours, use \(1,\ldots,n\) on one side and \(2,\ldots,n+1\) on the other.
Theorem 3.10.3 (Collins–Trenk; Klavžar–Wong–Zhu, 2006). For every connected graph \(G\), \(D(G)\leqslant\Delta(G)+1\), with equality if and only if \(G\) is \(K_n\), \(K_{n,n}\) or \(C_5\).
We do not prove this theorem. Instead, here is a pure counting argument that often gives much better bounds. The motion \(m(G)\) is the least number of vertices moved by a non-trivial automorphism.
Theorem 3.10.4 (Motion lemma, Russell–Sundaram, 1998). If \(k^{m(G)/2}>|\mathrm{Aut}(G)|\), then \(D(G)\leqslant k\).
Proof. A non-trivial automorphism \(\gamma\) moves some number \(m'\geqslant m=m(G)\) of vertices, so it has at most \(m'/2\) cycles among them and at most \(n-m'/2\leqslant n-m/2\) cycles in all. Hence at most \(k^{n-m/2}\) colourings are fixed by \(\gamma\). The number of colourings fixed by some non-trivial automorphism is at most \((|\mathrm{Aut}(G)|-1)k^{n-m/2}<k^n\), so some colouring is fixed by none.
Example 3.10.5. In \(Q_n\) the transposition of two coordinates fixes the \(2^{n-1}\) words whose two coordinates agree and moves the other \(2^{n-1}\); one can show that no non-trivial automorphism moves fewer, so \(m(Q_n)=2^{n-1}\). Since \(|\mathrm{Aut}(Q_n)|=2^nn!\) and \(2^{2^{n-2}}>2^nn!\) for \(n\geqslant6\), the motion lemma gives \(D(Q_n)=2\) for \(n\geqslant6\). A computer search settles \(n=4,5\), and \(D(Q_2)=D(Q_3)=3\).
Let \(\Phi_k(G)\) be the number of distinguishing colourings \(V(G)\to[k]\). Since \(\mathrm{Aut}(G)\) acts on them with trivial stabilisers, Theorem 3.6.2 says that every orbit has exactly \(|\mathrm{Aut}(G)|\) elements, so the number of distinguishing colourings up to symmetry is \(\Phi_k(G)/|\mathrm{Aut}(G)|\).
Proposition 3.10.6. Let \(\Gamma=\mathrm{Aut}(G)\), and for a subgroup \(H\leqslant\Gamma\) let \(o(H)\) be the number of orbits of \(H\) on \(V(G)\). Then \[\Phi_k(G)=\sum_{H\leqslant\Gamma}\mu(1,H)\,k^{\,o(H)},\] where \(\mu\) is the Möbius function of the lattice of subgroups of \(\Gamma\).
Proof. For a colouring \(c\) the colour-preserving automorphisms form a subgroup \(\Gamma_c\). The colourings fixed by every element of \(H\) are those constant on the orbits of \(H\), so \(k^{o(H)}=\sum_{K\geqslant H}f(K)\), where \(f(K)\) is the number of colourings with \(\Gamma_c=K\). By the reversed form of Theorem 2.7.2, \(f(1)=\sum_{H}\mu(1,H)k^{o(H)}\), and \(f(1)=\Phi_k(G)\).
Example 3.10.7. For \(C_6\), \(\Phi_2=12\): the twelve images of the colouring of Proposition 3.10.2(c) under the \(12\) symmetries of the hexagon, and nothing else. So up to symmetry there is exactly one distinguishing \(2\)-colouring of the hexagon. With three colours \(\Phi_3(C_6)=444\), giving \(37\) classes.
Grouping the distinguishing colourings by the partition of \(V(G)\) into colour classes leads to a family of numbers that behaves like the Stirling numbers of the second kind.
Definition 3.10.8. A partition of \(V(G)\) into blocks is distinguishing if the only automorphism that maps every block onto itself is the identity. The distinguishing Stirling number \(\left\{ {G \atop k} \right\}_D\) is the number of distinguishing partitions of \(V(G)\) into exactly \(k\) non-empty blocks.
Proposition 3.10.9. For every graph \(G\) on \(n\) vertices and every \(k\), \[\Phi_k(G)=\sum_{j=1}^n\left\{ {G \atop j} \right\}_D k^{\underline j}.\] Moreover \(\left\{ {G \atop j} \right\}_D=0\) for \(j<D(G)\), \(\left\{ {G \atop n} \right\}_D=1\), and if \(G\) is asymmetric then \(\left\{ {G \atop j} \right\}_D=S(n,j)\) for all \(j\).
Proof. A colouring that uses exactly \(j\) colours is a partition into \(j\) blocks together with an injective assignment of colours to the blocks, and it is distinguishing exactly when the partition is. There are \(k^{\underline j}\) injective assignments. The other statements follow from the definitions.
For \(C_6\) the numbers are \(0,6,68,62,15,1\), and indeed \(6\cdot6+68\cdot6=444=\Phi_3(C_6)\). For \(Q_3\) they are \(0,0,456,1312,960,260,28,1\), so \(\Phi_3(Q_3)=456\cdot6=2736\) and there are \(2736/48=57\) distinguishing \(3\)-colourings of the cube up to symmetry.
From the authors’ research
M. H. Shekarriz, D. Yaqubi and M. Mirzavaziri, Distinguishing Stirling numbers (title to be confirmed) · preprint
[Authors: summarise the main results of the preprint in three or four sentences: the notation, the recurrences or identities you prove for \(\left\{ {G \atop k} \right\}_D\), the families for which you have closed forms, and the link to multiplicative partitions if it appears in the paper. Add the arXiv link. Check that the definition above matches the paper.]
import networkx as nx
from networkx.algorithms.isomorphism import GraphMatcher
from math import prod
def nontrivial_automorphisms(G):
V = list(G)
return [a for a in GraphMatcher(G, G).isomorphisms_iter() if any(a[v] != v for v in V)]
def set_partitions(n, k):
# restricted growth strings: block of vertex i is r[i], first occurrences in order 0, 1, 2, ...
def rec(i, m, cur):
if i == n:
if m == k: yield cur
return
for b in range(min(m + 1, k)):
yield from rec(i + 1, max(m, b + 1), cur + [b])
yield from rec(0, 0, [])
def dist_stirling(G):
V, A = list(G), nontrivial_automorphisms(G)
row = []
for k in range(1, len(V) + 1):
cnt = 0
for r in set_partitions(len(V), k):
c = dict(zip(V, r))
if all(any(c[a[v]] != c[v] for v in V) for a in A):
cnt += 1
row.append(cnt)
return row
def phi(row, k):
return sum(T * prod(range(k - j + 1, k + 1)) for j, T in enumerate(row, start=1))
for name, G in [("P_4", nx.path_graph(4)), ("C_5", nx.cycle_graph(5)), ("C_6", nx.cycle_graph(6)),
("K_3,3", nx.complete_bipartite_graph(3, 3)), ("Q_3", nx.hypercube_graph(3))]:
row = dist_stirling(G)
D = next(k for k in range(1, 10) if phi(row, k) > 0)
print(f"{name:6s} D = {D} numbers {row} Phi_2..4 = {[phi(row, k) for k in (2, 3, 4)]}")
Research thread · Distinguishing numbers of families
The distinguishing number is known for many families: paths, cycles, hypercubes, Cartesian powers of graphs (Imrich and Klavžar), Kneser graphs, and trees, for which there is a polynomial algorithm. For most families the counting question is open: how many distinguishing \(k\)-colourings, or distinguishing partitions, does the family have? Pick a family, compute the distinguishing Stirling numbers for small members with the program of this section, and look for recurrences in the style of Chapter 4.
Reading: M. O. Albertson and K. L. Collins, Symmetry breaking in graphs, Electron. J. Combin. 3 (1996); W. Imrich and S. Klavžar, Distinguishing Cartesian powers of graphs, J. Graph Theory 53 (2006).
Exercise 3.10.1 Pure
Check by hand that \(C_3\), \(C_4\) and \(C_5\) have no distinguishing \(2\)-colouring.
Exercise 3.10.2 Pure
Find \(D(K_{4,4})\) and the number of distinguishing \(5\)-colourings of \(K_{4,4}\) up to symmetry.
Each side must receive \(4\) distinct colours, and the two sides must not receive the same set of colours.
Exercise 3.10.3 Pure Code
How many distinguishing \(3\)-colourings of the Petersen graph are there up to symmetry?
The Petersen graph has \(35\,280\) distinguishing \(3\)-colourings and \(120\) automorphisms.
Exercise 3.10.4 Pure
Show that \(D(P_n)=2\) and count the distinguishing \(2\)-colourings of \(P_n\).
A \(2\)-colouring of a path is distinguishing unless it reads the same backwards.
Exercise 3.10.5 Code
Compute the motion of \(Q_4\) and \(Q_5\), and find distinguishing \(2\)-colourings of both by a random search.
Exercise 3.10.6 Pure
Show that \(\left\{ {K_n \atop k} \right\}_D=0\) for \(k<n\), and compute \(\left\{ {K_{1,3} \atop k} \right\}_D\) for \(k=1,2,3,4\).
Exercise 3.10.7 Research Project
A project: distinguishing Stirling numbers of cycles.
The subgroups of \(D_n\) are the rotation subgroups \(\langle\rho^{n/d}\rangle\) and the dihedral subgroups generated by a rotation subgroup and one reflection.
A recurrence answers a counting question by reducing it to smaller instances of the same question. For graphs the most natural way to make an instance smaller is to remove one edge. There are two ways to remove an edge \(e=uv\): delete it, giving \(G-e\), or contract it, giving \(G/e\), in which \(u\) and \(v\) are merged into one vertex adjacent to all neighbours of both. Contraction may create parallel edges and, if \(e\) had a parallel copy, a loop, so in this section graphs are multigraphs.
Definition 4.1.1. For an edge \(e=uv\) of a multigraph \(G\), the deletion \(G-e\) removes \(e\) and keeps everything else; the contraction \(G/e\) removes \(e\), identifies \(u\) and \(v\), and keeps all other edges, including those that become parallel or become loops.
Theorem 4.1.2. If \(e\) is not a loop, then \(\tau(G)=\tau(G-e)+\tau(G/e)\).
Proof. Split the spanning trees of \(G\) according to whether they contain \(e\). Those that avoid \(e\) are the spanning trees of \(G-e\). Those that contain \(e\) correspond, by contracting \(e\), to the spanning trees of \(G/e\): a set \(T\) of edges with \(e\in T\) is a spanning tree of \(G\) exactly when \(T\setminus\{e\}\) is a spanning tree of \(G/e\).
The recurrence ends at graphs whose edges are all loops; such a graph has one spanning tree if it has one vertex and none otherwise. A careless implementation takes \(2^{|E|}\) steps, so as a method of computation deletion–contraction is far worse than the Matrix-Tree Theorem. Its value is in proofs: a quantity that satisfies the same recurrence and the same initial values must be equal to \(\tau\).
Theorem 4.1.3 (Birkhoff–Whitney). If \(e\) is not a loop, then \(P(G,k)=P(G-e,k)-P(G/e,k)\). If \(G\) has a loop, \(P(G,k)=0\).
Proof. The proper colourings of \(G-e\) are of two kinds: those in which \(u\) and \(v\) get different colours, which are exactly the proper colourings of \(G\), and those in which they get the same colour, which correspond to the proper colourings of \(G/e\).
Starting from \(P(\overline{K_n},k)=k^n\) and applying Theorem 4.1.3, induction on \(|E|\) proves again that \(P(G,k)\) is a polynomial in \(k\) (Corollary 2.6.5). It also shows that its coefficients alternate in sign. For example, for a tree on \(n\) vertices, deleting a leaf edge disconnects a vertex and contracting it gives a tree on \(n-1\) vertices, so \(P(T,k)=kP(T',k)-P(T',k)=(k-1)P(T',k)\) and \(P(T,k)=k(k-1)^{n-1}\).
Two more polynomials obey similar rules. Let \(m_j(G)\) be the number of matchings with \(j\) edges and \(i_j(G)\) the number of independent sets with \(j\) vertices. The Hosoya index \(Z(G)=\sum_jm_j(G)\) is the number of all matchings, including the empty one, and the Merrifield–Simmons index \(\sigma(G)=\sum_ji_j(G)\) is the number of all independent sets.
Proposition 4.1.4. For an edge \(e=uv\) and a vertex \(v\) of a graph \(G\): \[Z(G)=Z(G-e)+Z(G-u-v),\qquad \sigma(G)=\sigma(G-v)+\sigma(G-N[v]).\] More precisely \(m_j(G)=m_j(G-e)+m_{j-1}(G-u-v)\) and \(i_j(G)=i_j(G-v)+i_{j-1}(G-N[v])\).
Proof. A matching either avoids \(e\), and is a matching of \(G-e\), or contains \(e\), and the rest is a matching of \(G-u-v\). An independent set either avoids \(v\), or contains \(v\) and none of its neighbours.
Haruo Hosoya introduced his index in 1971 as a number that correlates with the boiling points of alkanes; Richard Merrifield and Howard Simmons used independent sets in the same way in the 1980s. Chemists call such numbers topological indices, and hundreds of them are in use.
The three recurrences above have the same shape: a quantity of \(G\) is a combination of the same quantity for \(G-e\) and \(G/e\) (or a related smaller graph). Tutte found the most general invariant of this kind. Write \(r(A)\) for the number of vertices minus the number of components of the spanning subgraph \((V,A)\); this is the size of a spanning forest of \((V,A)\), the rank of \(A\).
Definition 4.1.5. The Tutte polynomial of a multigraph \(G=(V,E)\) is \[T(G;x,y)=\sum_{A\subseteq E}(x-1)^{\,r(E)-r(A)}\,(y-1)^{\,|A|-r(A)}.\]
Theorem 4.1.6. \(T\) is determined by the rules: \(T=1\) for a graph with no edges; if \(e\) is a bridge, \(T(G)=x\,T(G/e)\); if \(e\) is a loop, \(T(G)=y\,T(G-e)\); otherwise \(T(G)=T(G-e)+T(G/e)\).
Proof. Split the sum according to whether \(e\in A\). If \(e\) is neither a bridge nor a loop, the subsets avoiding \(e\) have the same rank in \(G\) and in \(G-e\), and \(r(E)\) does not change, so they give \(T(G-e)\); for subsets containing \(e\), contraction lowers both \(r(A)\) and \(r(E)\) by one and \(|A|\) by one, so they give \(T(G/e)\). If \(e\) is a bridge, both parts equal \(T(G/e)\) up to a factor: removing a bridge from \(A\) lowers \(r(A)\) by one, which multiplies the term by \(x-1\), so the total is \((x-1)T(G/e)+T(G/e)=xT(G/e)\). A loop is similar with \(y-1\).
Proposition 4.1.7. For a connected graph \(G\) with \(n\) vertices:
\(T(G;1,1)=\tau(G)\); \(T(G;2,1)\) is the number of forests (acyclic edge sets); \(T(G;1,2)\) is the number of connected spanning subgraphs; \(T(G;2,2)=2^{|E|}\).
\(P(G,k)=(-1)^{n-1}k\,T(G;1-k,0)\).
\(T(G;2,0)\) is the number of acyclic orientations of \(G\).
Proof. (a) At \(x=y=1\) only the terms with both exponents \(0\) survive: \(r(A)=n-1\) and \(|A|=r(A)\), that is, \(A\) is a spanning tree. At \((2,1)\) the terms with \(|A|=r(A)\) survive, which are the forests; at \((1,2)\) those with \(r(A)=r(E)\), the connected spanning subgraphs.
Both sides satisfy the recurrence of Theorem 4.1.3 after the substitution, as one checks for bridges, loops and ordinary edges, and they agree for graphs without edges.
Let \(a(G)\) be the number of acyclic orientations. For an edge \(e=uv\) that is neither a bridge nor a loop, each acyclic orientation of \(G-e\) extends to \(G\) in one or two ways, and it extends in two ways exactly when it comes from an acyclic orientation of \(G/e\); so \(a(G)=a(G-e)+a(G/e)\). A bridge can be oriented either way, so \(a(G)=2a(G/e)\), and a loop gives \(a(G)=0\). These are the rules of Theorem 4.1.6 at \((2,0)\).
Richard P. Stanley (born 1944)
American combinatorialist at MIT, author of the two volumes of Enumerative Combinatorics. In 1973 he proved that \((-1)^nP(G,-1)\) is the number of acyclic orientations of \(G\), the first of many “combinatorial reciprocity” theorems.
Example 4.1.8. For \(K_4\), \[T(K_4;x,y)=x^3+3x^2+2x+4xy+2y+3y^2+y^3.\] So \(K_4\) has \(T(1,1)=16\) spanning trees, \(T(2,1)=38\) forests, \(38\) connected spanning subgraphs, and \(T(2,0)=24\) acyclic orientations, one for each ordering of the vertices. Substituting into (b) gives \(P(K_4,k)=k(k-1)(k-2)(k-3)\). For the Petersen graph the same values are \(2000\), \(22\,292\), \(5968\) and \(16\,680\).
Theorem 4.1.9 (Recipe theorem, Oxley–Welsh). Let \(f\) be an invariant of multigraphs, multiplicative over disjoint unions and one-point joins, with \(f=1\) on the graph with one vertex, and suppose there are constants \(a,b\neq0\) such that \(f(G)=af(G-e)+bf(G/e)\) for every edge that is neither a bridge nor a loop. Then \(f\) is an evaluation of the Tutte polynomial: \[f(G)=a^{|E|-r(E)}\,b^{\,r(E)}\;T\Big(G;\frac{f(K_2)}b,\frac{f(\text{loop})}a\Big).\]
We do not prove it. The recipe explains why so many counting problems, from spanning trees to network reliability, the Ising and Potts models of physics and the Jones polynomial of knots, all turn out to be specialisations of one polynomial.
import itertools as it
import networkx as nx
import sympy as sp
x, y = sp.symbols("x y")
def tutte(G):
# sum over all edge subsets, with a union-find to compute ranks
V, E = list(G), list(G.edges())
idx = {v: i for i, v in enumerate(V)}
def rank(A):
p = list(range(len(V)))
def find(a):
while p[a] != a:
p[a] = p[p[a]]; a = p[a]
return a
r = 0
for i in A:
a, b = find(idx[E[i][0]]), find(idx[E[i][1]])
if a != b:
p[a] = b; r += 1
return r
rE, total = rank(range(len(E))), 0
for mask in range(1 << len(E)):
A = [i for i in range(len(E)) if mask >> i & 1]
rA = rank(A)
total += (x - 1) ** (rE - rA) * (y - 1) ** (len(A) - rA)
return sp.expand(total)
for name, G in [("K_4", nx.complete_graph(4)), ("C_5", nx.cycle_graph(5)), ("Petersen", nx.petersen_graph())]:
T = tutte(G)
vals = [T.subs({x: a, y: b}) for a, b in [(1, 1), (2, 1), (1, 2), (2, 0)]]
print(name, "trees, forests, connected spanning subgraphs, acyclic orientations:", vals)
print(tutte(nx.complete_graph(4)))
Exercise 4.1.1 Pure
Use Theorem 4.1.2 to show that \(\tau(C_n)=n\) and that the graph formed by two vertices joined by \(m\) parallel edges has \(m\) spanning trees.
Exercise 4.1.2 Pure
Compute \(T(C_n;x,y)\), and check (b) of Proposition 4.1.7 against \(P(C_n,k)=(k-1)^n+(-1)^n(k-1)\).
Delete one edge: \(C_n-e\) is a path, all of whose edges are bridges, and \(C_n/e=C_{n-1}\).
\(T(C_n)=x^{n-1}+x^{n-2}+\cdots+x+y\).
Exercise 4.1.3 Pure
Show that the number of acyclic orientations of \(K_n\) is \(n!\), and that of \(C_n\) is \(2^n-2\). How many acyclic orientations has the wheel \(W_4\)?
Use (c) of Proposition 4.1.7 or Stanley’s formula \(a(G)=(-1)^{|V(G)|}P(G,-1)\) (note that \(W_n\) has \(n+1\) vertices), with \(P(W_n,k)=k\big((k-2)^n+(-1)^n(k-2)\big)\).
Exercise 4.1.4 Pure
Prove that \(Z(K_n)\) is the number of involutions of \([n]\) and satisfies \(Z(K_n)=Z(K_{n-1})+(n-1)Z(K_{n-2})\).
Exercise 4.1.5 Code
Compute the Hosoya and Merrifield–Simmons indices of the Petersen graph with the recurrences of Proposition 4.1.4.
Exercise 4.1.6 Computer Science Algorithm
Deletion–contraction takes exponential time in general. Implement it with a cache of the graphs already met, up to isomorphism, and observe how many distinct graphs appear when computing \(T(G)\) for ladders \(P_2\,\square\,P_n\) and for grids. Then read about Noble’s algorithm (1998), which computes \(T(G)\) in polynomial time for graphs of bounded treewidth by dynamic programming over a tree decomposition, and about the algorithm of Björklund, Husfeldt, Kaski and Koivisto, which computes the Tutte polynomial of any graph in time \(2^nn^{O(1)}\).
Exercise 4.1.7 Research Project
A project: the matching polynomial. Define \(\mu(G,x)=\sum_j(-1)^jm_j(G)x^{n-2j}\).
In a family of graphs \(G_1,G_2,\ldots\) built in a regular way, the recurrences of Section 4.1 usually close up: removing an edge or a vertex from \(G_n\) leaves \(G_{n-1}\) or \(G_{n-2}\), perhaps with a small attachment. The answer is then a linear recurrence with constant coefficients, and the numbers are relatives of Fibonacci’s.
Édouard Lucas (1842–1891)
French mathematician who studied the sequences now named after Fibonacci and himself, and gave the Fibonacci numbers their name. He invented the Tower of Hanoi puzzle (1883) and a test for Mersenne primes still in use.
Proposition 4.2.1. Let \(F_1=F_2=1\) and \(L_1=1\), \(L_2=3\), with \(F_{n}=F_{n-1}+F_{n-2}\) and \(L_n=L_{n-1}+L_{n-2}\). Then \[Z(P_n)=F_{n+1},\qquad \sigma(P_n)=F_{n+2},\qquad Z(C_n)=\sigma(C_n)=L_n\quad(n\geqslant3).\]
Proof. Apply Proposition 4.1.4 at an end vertex \(v\) of \(P_n\) and its edge \(e\): \(Z(P_n)=Z(P_{n-1})+Z(P_{n-2})\) and \(\sigma(P_n)=\sigma(P_{n-1})+\sigma(P_{n-2})\), with \(Z(P_1)=1\), \(Z(P_2)=2\), \(\sigma(P_1)=2\), \(\sigma(P_2)=3\). For the cycle, delete an edge \(e\): \(Z(C_n)=Z(P_n)+Z(P_{n-2})=F_{n+1}+F_{n-1}=L_n\). Similarly \(\sigma(C_n)=\sigma(P_{n-1})+\sigma(P_{n-3})=F_{n+1}+F_{n-1}\).
Example 4.2.2. By Theorem 4.1.3, \(P(C_n,k)=P(P_n,k)-P(C_{n-1},k)=k(k-1)^{n-1}-P(C_{n-1},k)\). With \(P(C_3,k)=k(k-1)(k-2)\) this gives by induction \[P(C_n,k)=(k-1)^n+(-1)^n(k-1).\] The wheel \(W_n=C_n+K_1\) needs one colour for the centre that the rim cannot use, so \(P(W_n,k)=k\,P(C_n,k-1)=k\big((k-2)^n+(-1)^n(k-2)\big)\). For instance \(W_4\) has \(72\) proper \(4\)-colourings and \(W_5\) has \(120\).
In Section 3.2 a computer suggested that \(\tau(F_n)=F_{2n}\) for the fan \(F_n=P_n+K_1\) and \(\tau(W_n)=L_{2n}-2\) for the wheel. Here are the proofs.
Proposition 4.2.3. \(\tau(F_1)=1\), \(\tau(F_2)=3\) and \(\tau(F_n)=3\tau(F_{n-1})-\tau(F_{n-2})\); hence \(\tau(F_n)=F_{2n}\).
Proof. Let the path be \(v_1\cdots v_n\) and the centre \(c\). Let \(f_n=\tau(F_n)\) and let \(k_n\) be the number of spanning trees of \(F_n/cv_n\). Apply Theorem 4.1.2 to the edge \(v_{n-1}v_n\). Deleting it leaves \(F_{n-1}\) with a pendant edge \(cv_n\), so \(f_{n-1}\) trees. Contracting it gives \(F_{n-1}\) with the edge \(cv_{n-1}\) doubled; split once more on one copy of this double edge to get \(f_{n-1}+k_{n-1}\). So \(f_n=2f_{n-1}+k_{n-1}\). In the same way, \(F_n/cv_n\) is \(F_{n-1}\) with \(cv_{n-1}\) doubled, so \(k_n=f_{n-1}+k_{n-1}\). The matrix \(\begin{pmatrix}2&1\\1&1\end{pmatrix}\) has characteristic polynomial \(\lambda^2-3\lambda+1\), which gives the recurrence; and \(F_{2n}=3F_{2n-2}-F_{2n-4}\) with \(F_2=1\), \(F_4=3\).
The same kind of argument, applied to a rim edge of \(W_n\), gives \(\tau(W_n)=L_{2n}-2\); we leave it as an exercise. The ladder \(P_2\,\square\,P_n\) gives \(\tau_n=4\tau_{n-1}-\tau_{n-2}\), as found in Section 3.2.
In every case the recurrence came from a small system of recurrences, that is, from a matrix acting on a vector of a few related counts. Section 4.3 turns this observation into a method.
Exercise 4.2.1 Pure
Show that \(\sigma(P_n)=F_{n+2}\) by a bijection with binary words of length \(n\) with no two consecutive ones.
Exercise 4.2.2 Pure
Prove that \(\tau(W_n)=L_{2n}-2\) for \(n\geqslant3\).
Apply deletion–contraction to the rim edge \(v_nv_1\): \(W_n-v_nv_1=F_n\).
Use \(L_{2n}=F_{2n-1}+F_{2n+1}\).
Exercise 4.2.3 Math Olympiad
In how many ways can \(n\) people sitting at a round table be partitioned into pairs of neighbours and single people? (Each person is in at most one pair.)
Exercise 4.2.4 Pure
Find \(Z\) and \(\sigma\) for the star \(K_{1,n}\) and the complete bipartite graph \(K_{2,n}\).
\(\sigma(K_{1,n})=2^n+1\).
An independent set of \(K_{2,n}\) lies on one side.
Exercise 4.2.5 Pure
Show that the number of proper \(3\)-colourings of the ladder \(P_2\,\square\,P_n\) is \(6\cdot3^{n-1}\).
Given the colours of one rung, count the colourings of the next rung.
Exercise 4.2.6 Code
Compute \(\sigma(Q_3)\) and \(Z(Q_3)\).
How many independent sets has the grid \(P_m\,\square\,P_n\)? For \(m=1\) the answer is \(F_{n+2}\). For \(m=2\), look at the grid one column at a time: a column is empty, has its top vertex, or has its bottom vertex, and two neighbouring columns are compatible when they do not both use the same row. Counting column sequences is counting walks in a small graph, and that is a matrix power.
Theorem 4.3.1 (Transfer-matrix method). Let \(S\) be a finite set of states, \(T\) an \(S\times S\) matrix of non-negative integers, and \(u,v\) vectors indexed by \(S\). Then \(a_n=u^{\mathsf T}T^{\,n-1}v\) satisfies the linear recurrence with constant coefficients given by the characteristic polynomial of \(T\): if \(\det(\lambda I-T)=\lambda^d-c_1\lambda^{d-1}-\cdots-c_d\), then \[a_n=c_1a_{n-1}+c_2a_{n-2}+\cdots+c_da_{n-d}\qquad(n>d).\] Moreover, if \(T\) is primitive (some power of \(T\) has all entries positive) and \(u,v\) are non-negative and non-zero, then \(a_n\) grows like \(c\,\lambda_{\max}^n\), where \(\lambda_{\max}\) is the largest eigenvalue of \(T\) and \(c>0\).
Proof. By the Cayley–Hamilton theorem \(T^d=c_1T^{d-1}+\cdots+c_dI\). Multiply by \(u^{\mathsf T}T^{\,n-1-d}\) on the left and by \(v\) on the right. For the growth, write \(v\) in terms of the (generalised) eigenvectors of \(T\); for a primitive \(T\) the Perron–Frobenius theorem says that \(\lambda_{\max}\) is real, positive, simple and larger in absolute value than the other eigenvalues, with an eigenvector whose entries are all positive, so \(u\) and \(v\) have non-zero components along it.
Example 4.3.2. For the \(2\times n\) grid the states are \(\varnothing\), \(\{\text{top}\}\), \(\{\text{bottom}\}\) and \[T=\begin{pmatrix}1&1&1\\1&0&1\\1&1&0\end{pmatrix},\qquad \det(\lambda I-T)=(\lambda+1)(\lambda^2-2\lambda-1).\] So \(a_n=a_{n-1}+3a_{n-2}+a_{n-3}\); in fact the shorter recurrence \(a_n=2a_{n-1}+a_{n-2}\) already holds, because the vector \(u=v=\mathbf 1\) is orthogonal to the eigenvector of \(-1\). The values are \(3,7,17,41,99,239,\ldots\), and \(a_n\approx c(1+\sqrt2)^n\).
The same method handles perfect matchings (domino tilings, the states being the sets of cells of a column already covered by horizontal dominoes from the left), proper colourings (states are proper colourings of a column), cylinders \(C_m\,\square\,P_n\), and many more. The price is the number of states, which grows exponentially in \(m\): the method gives, for each fixed \(m\), a recurrence in \(n\).
Proposition 4.3.3. The numbers of independent sets of \(P_m\,\square\,P_n\) for small \(m\) are:
| \(m\backslash n\) | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 5 | 8 | 13 | 21 |
| 2 | 3 | 7 | 17 | 41 | 99 | 239 |
| 3 | 5 | 17 | 63 | 227 | 827 | 2999 |
| 4 | 8 | 41 | 227 | 1234 | 6743 | 36787 |
import itertools as it
from fractions import Fraction
def column_states(m, kind):
if kind == "ind": # independent sets of a column P_m
return [S for S in it.product((0, 1), repeat=m) if all(not (S[i] and S[i + 1]) for i in range(m - 1))]
if kind == "col3": # proper 3-colourings of a column
return [S for S in it.product(range(3), repeat=m) if all(S[i] != S[i + 1] for i in range(m - 1))]
def compatible(S, R, kind):
if kind == "ind":
return all(not (a and b) for a, b in zip(S, R))
if kind == "col3":
return all(a != b for a, b in zip(S, R))
def terms(m, kind, N):
st = column_states(m, kind)
vec = [1] * len(st)
out = [sum(vec)]
for _ in range(N - 1):
vec = [sum(vec[i] for i, S in enumerate(st) if compatible(S, R, kind)) for R in st]
out.append(sum(vec))
return out
def berlekamp_massey(a):
# shortest linear recurrence over the rationals: a_n = sum c_i a_{n-i}
a = [Fraction(x) for x in a]
C, B, L, m, b = [Fraction(1)], [Fraction(1)], 0, 1, Fraction(1)
for n in range(len(a)):
d = a[n] + sum(C[i] * a[n - i] for i in range(1, L + 1))
if d == 0:
m += 1; continue
T = C[:]
coef = d / b
C = C + [Fraction(0)] * (len(B) + m - len(C))
for i, x in enumerate(B):
C[i + m] -= coef * x
if 2 * L <= n:
L, B, b, m = n + 1 - L, T, d, 1
else:
m += 1
return [-c for c in C[1:L + 1]]
for kind in ("ind", "col3"):
for m in range(1, 5):
a = terms(m, kind, 24)
rec = berlekamp_massey(a)
print(kind, "m =", m, a[:6], " recurrence coefficients:", [str(c) for c in rec])
Research thread · Hard squares
For each fixed \(m\) the independent sets of \(P_m\,\square\,P_n\) satisfy a linear recurrence in \(n\), but the order of the recurrence grows exponentially with \(m\), and no formula in both variables is known. Even the growth constant \[\kappa=\lim_{m,n\to\infty}\sigma(P_m\,\square\,P_n)^{1/mn}=1.50304808\ldots,\] the hard-square entropy of statistical physics, has no known closed form, in contrast with the domino constant \(e^{G/\pi}\) of Section 3.5. Baxter computed many digits by the corner transfer-matrix method. Compute upper and lower bounds for \(\kappa\) from transfer matrices of cylinders, and see how far you get.
Reading: R. J. Baxter, Planar lattice gases with nearest-neighbour exclusion, Ann. Comb. 3 (1999); N. J. Calkin and H. S. Wilf, The number of independent sets in a grid graph, SIAM J. Discrete Math. 11 (1998).
Exercise 4.3.1 Pure
Show that the number of proper \(3\)-colourings of \(P_3\,\square\,P_n\) satisfies a linear recurrence of order at most \(3\), find it, and compute the value for \(n=4\).
A proper \(3\)-colouring of a column of three cells is of type \(aba\) or \(abc\); there are \(6\) of each.
Exercise 4.3.2 Code
Find the shortest linear recurrence for the number of independent sets of \(P_3\,\square\,P_n\).
Exercise 4.3.3 Pure Math Olympiad
How many ways are there to place non-attacking kings on a \(2\times n\) board (any number of kings, including none)?
Kings on a \(2\times n\) board attack each other when they are in the same or adjacent columns; so each column has at most one king, and two consecutive columns cannot both have one.
Exercise 4.3.4 Pure
Use the transfer-matrix method to count the perfect matchings of the cylinder \(C_4\,\square\,P_n\) for \(n\leqslant6\).
Exercise 4.3.5 Informatics Olympiad Algorithm
A \(m\times n\) board with \(m\leqslant10\) and \(n\leqslant10^{18}\) is given. Explain how to compute the number of its domino tilings modulo \(10^9+7\) quickly.
States are subsets of a column (\(2^m\) of them); use fast exponentiation of the transfer matrix.
Exercise 4.3.6 Research Project
A project: the order of the recurrences. Let \(d_m\) be the order of the shortest linear recurrence for \(\sigma(P_m\,\square\,P_n)\) as a function of \(n\).
Section 1.10 promised a proof of the recurrence for the number \(\mathcal C_n\) of connected graphs on \([n]\), and of its version for graphs with a given number of components. The argument is the oldest one in this book: it goes back to the 2014 Persian edition. We give it in two forms and then use the same idea, “cut the graph where it is least connected”, to count graphs with no cut vertex.
Theorem 4.4.1. For every \(n\geqslant1\), \[n\,2^{\binom n2}=\sum_{k=1}^nk\binom nk\,2^{\binom{n-k}2}\,\mathcal C_k,\qquad 2^{\binom n2}=\sum_{k=1}^n\binom{n-1}{k-1}\,2^{\binom{n-k}2}\,\mathcal C_k.\]
Proof. Count the graphs on \([n]\) with one starred vertex. Directly, there are \(n\,2^{\binom n2}\). Alternatively, let \(k\) be the number of vertices of the component containing the star. Choose its vertex set (\(\binom nk\) ways), the starred vertex in it (\(k\) ways), a connected graph on it (\(\mathcal C_k\) ways) and any graph on the remaining \(n-k\) vertices (\(2^{\binom{n-k}2}\) ways). Nothing is counted twice, because the star tells us which component was built first. This proves the first identity. For the second, star vertex \(1\) instead of an arbitrary vertex: the component of \(1\) is chosen in \(\binom{n-1}{k-1}\) ways.
Example 4.4.2. With \(\mathcal C_1,\ldots,\mathcal C_4=1,1,4,38\) the first identity for \(n=5\) reads \[5\cdot2^{10}=320+160+240+760+5\,\mathcal C_5,\] so \(\mathcal C_5=728\). This is the computation of the 2014 edition.
Theorem 4.4.3. Let \(n_1\geqslant n_2\geqslant\cdots\geqslant n_k\geqslant1\) with \(n_1+\cdots+n_k=n\), and let \(a_1,\ldots,a_\ell\) be the multiplicities of the distinct values among the \(n_i\). The number of graphs on \([n]\) whose components have exactly the sizes \(n_1,\ldots,n_k\) is \[\frac{n!}{n_1!\cdots n_k!\;a_1!\cdots a_\ell!}\;\mathcal C_{n_1}\cdots\mathcal C_{n_k}.\] Consequently the number \(g(n,k)\) of graphs on \([n]\) with exactly \(k\) components satisfies \[g(n,k)=\sum_{j=1}^{n}\binom{n-1}{j-1}\,\mathcal C_j\;g(n-j,k-1),\qquad g(0,0)=1.\]
Proof. Choose the vertex sets of the components in order, \(\binom{n}{n_1}\binom{n-n_1}{n_2}\cdots=\frac{n!}{n_1!\cdots n_k!}\) ways. Components of equal size have been ordered, which we must forget: divide by \(a_1!\cdots a_\ell!\). Then put a connected graph on each set. For the recurrence, let \(j\) be the size of the component of vertex \(1\), as in Theorem 4.4.1.
For \(n=5\) the numbers \(g(5,k)\) are \(728,230,55,10,1\), which add up to \(2^{10}=1024\); the disconnected graphs number \(230+55+10+1=296\), as in the 2014 edition. The table \(g(n,k)\) is a relative of the Stirling numbers: replacing \(\mathcal C_j\) by \(1\) gives exactly \(S(n,k)\), and replacing it by \((j-1)!\) gives \(c(n,k)\). We return to such triangles in Section 4.6.
Definition 4.4.4. A cut vertex of a connected graph is a vertex whose removal disconnects it. A connected graph with at least two vertices and no cut vertex is 2-connected; by convention \(K_2\) counts as 2-connected. A block of a graph is a maximal connected subgraph without a cut vertex of its own.
Every edge lies in exactly one block, two blocks share at most one vertex, and that vertex is a cut vertex. So a connected graph is a tree-like arrangement of blocks glued at cut vertices. Seen from vertex \(1\): the blocks containing \(1\) are glued together at \(1\), and from every other vertex \(w\) of these blocks hangs a connected graph, rooted at \(w\), made of everything that is cut off from \(1\) by \(w\).
Theorem 4.4.5. Let \(b_k\) be the number of 2-connected graphs on \([k]\) and put \[d_m=\sum_{j\geqslant1}b_{j+1}\sum_{\{B_1,\ldots,B_j\}}\prod_{i=1}^j|B_i|\,\mathcal C_{|B_i|},\] the inner sum running over the partitions of an \(m\)-set into \(j\) blocks. Then \[\mathcal C_n=\sum_{\{D_1,\ldots,D_r\}}\prod_{i=1}^r d_{|D_i|},\] the sum running over the partitions of \(\{2,\ldots,n\}\). In the identity for \(\mathcal C_n\), the number \(b_n\) occurs only in the term \(d_{n-1}\) coming from the partition with a single part, with coefficient \(1\), and otherwise only \(b_2,\ldots,b_{n-1}\) occur; so the identity determines \(b_2,b_3,\ldots\) one after another.
Proof. Given a connected graph on \([n]\), group the vertices other than \(1\) according to the block at \(1\) through which they are reached from \(1\); this is the partition \(\{D_i\}\). For one group \(D\) of size \(m\), the block \(B\) at \(1\) has \(j+1\) vertices, namely \(1\) and \(j\) attachment vertices, and each attachment vertex \(w\) carries a connected graph on a set \(B_w\ni w\); the sets \(B_w\) partition \(D\). Choosing the partition of \(D\), a root \(w\) in each part, a connected graph on each part, and a 2-connected graph on \(\{1\}\cup\{\text{roots}\}\) gives the term of \(d_m\). Conversely these choices always produce a connected graph in which the given block is a block through \(1\), so the decomposition is a bijection.
The numbers of 2-connected graphs on \([n]\) for \(n=2,\ldots,7\) are \(1,1,10,238,11\,368,1\,014\,888\). Written with exponential generating functions (Chapter 5), Theorem 4.4.5 becomes the neat identity \(C'(x)=e^{B'(xC'(x))}\), due to Robinson and to Ford and Uhlenbeck.
from math import comb
from functools import lru_cache
N = 8
C = [0, 1]
for n in range(2, N + 1):
C.append(2 ** comb(n, 2) - sum(comb(n - 1, k - 1) * C[k] * 2 ** comb(n - k, 2) for k in range(1, n)))
# g(n, k): graphs on [n] with exactly k components
@lru_cache(None)
def gnk(n, k):
if n == 0:
return 1 if k == 0 else 0
if k == 0:
return 0
return sum(comb(n - 1, j - 1) * C[j] * gnk(n - j, k - 1) for j in range(1, n + 1))
for n in range(1, 7):
print(n, [gnk(n, k) for k in range(1, n + 1)], "sum =", sum(gnk(n, k) for k in range(1, n + 1)), "= 2^C(n,2) =", 2 ** comb(n, 2))
# "exponential" sums over set partitions, done with the usual recursion on the block of the smallest element
def part_sum(m, w):
# sum over partitions of an m-set of prod w(|block|)
P = [1] + [0] * m
for t in range(1, m + 1):
P[t] = sum(comb(t - 1, s - 1) * w(s) * P[t - s] for s in range(1, t + 1))
return P[m]
b = {2: 1}
def d(m):
# partitions of m vertices into j parts, each with a root and a connected graph: polynomial in the weights
total = 0
for j in range(1, m + 1):
if j + 1 in b:
# count partitions into exactly j parts with weight |B| C_|B|
@lru_cache(None)
def exact(t, parts):
if t == 0: return 1 if parts == 0 else 0
if parts == 0: return 0
return sum(comb(t - 1, s - 1) * s * C[s] * exact(t - s, parts - 1) for s in range(1, t + 1))
total += b[j + 1] * exact(m, j)
return total
for n in range(3, N + 1):
b[n] = 0
b[n] = C[n] - part_sum(n - 1, d)
print("2-connected graphs:", [b[k] for k in range(2, N + 1)])
The same kind of decomposition counts Eulerian graphs: the even graphs on \([n]\) number \(2^{\binom{n-1}2}\) (Theorem 2.1.1), and an even graph is a set of connected even graphs, so the second identity of Theorem 4.4.1 holds with \(2^{\binom m2}\) replaced by \(2^{\binom{m-1}2}\) and \(\mathcal C_k\) by the number of connected even graphs. This was Exercise 2.8.6.
Exercise 4.4.1 Pure
Show that the number of graphs on \([n]\) with exactly \(n-1\) components is \(\binom n2\), and that \(g(n,n-2)=4\binom n3+3\binom n4\).
Graphs with \(n-2\) components have either one component with \(3\) vertices or two components with \(2\) vertices each.
Exercise 4.4.2 Pure Code
Write a recurrence, in the style of Theorem 4.4.1, for the number \(c(n,m)\) of connected graphs on \([n]\) with \(m\) edges. Use it to count the connected graphs on \([n]\) with \(n\) edges (the unicyclic graphs) for \(n\leqslant6\).
The graphs on \([n]\) with \(m\) edges number \(\binom{\binom n2}m\); split according to the component of vertex \(1\) and its number of edges.
Exercise 4.4.3 Pure
Show that a connected graph with at least \(3\) vertices is 2-connected if and only if every two vertices lie on a common cycle.
Exercise 4.4.4 Pure
Use Theorem 4.4.5 to compute \(b_4=10\) by hand, and list the ten 2-connected graphs on \([4]\) by isomorphism type.
Types: \(C_4\) (\(3\) copies), \(K_4-e\) (\(6\)), \(K_4\) (\(1\)).
Exercise 4.4.5 Pure
A connected graph all of whose blocks are complete graphs is a block graph; if all blocks are single edges it is a tree. Find a recurrence for the number of block graphs on \([n]\) and compute it for \(n\leqslant6\).
Replace \(b_k\) by \(1\) for every \(k\geqslant2\) in Theorem 4.4.5.
Exercise 4.4.6 Research Project
A project: graphs with a given block structure. A cactus is a connected graph in which every block is an edge or a cycle.
Labeled trees have the closed formula \(n^{n-2}\). Unlabeled trees do not: their number has no formula, but it has an excellent recurrence. Cayley found it for rooted trees in 1857, and in 1874–75 he used such counts for the isomers of the alkanes; Otter showed in 1948 how to pass from rooted to free trees.
Definition 4.5.1. Let \(r_n\) be the number of unlabeled rooted trees with \(n\) vertices (isomorphism must map root to root), and \(t_n\) the number of unlabeled trees with \(n\) vertices.
Removing the root of a rooted tree leaves a multiset of rooted trees, whose sizes add up to \(n-1\), and every such multiset arises exactly once. So \(r_{n+1}\) is the number of multisets of rooted trees of total size \(n\).
Theorem 4.5.2 (Cayley, 1857). \(r_1=1\) and for \(n\geqslant1\) \[r_{n+1}=\frac1n\sum_{k=1}^n\Big(\sum_{d\mid k}d\,r_d\Big)\,r_{n-k+1}.\]
Proof. Let \(M_n\) be the set of multisets of rooted trees of total size \(n\), so \(|M_n|=r_{n+1}\). Count the pairs \((M,\text{a marked vertex of }M)\) with \(M\in M_n\): there are \(n\,r_{n+1}\). On the other hand, the marked vertex lies in one copy of some tree type \(T\) of size \(d\), which occurs in \(M\) with some multiplicity \(m_T\). Instead of marking a vertex in a copy, mark a vertex \(x\) of \(T\) (that is, \(d\) choices) and a number \(j\) with \(1\leqslant j\leqslant m_T\). Removing \(j\) copies of \(T\) from \(M\) leaves a multiset in \(M_{n-jd}\), and conversely any multiset in \(M_{n-jd}\) plus \(j\) copies of \(T\) gives back an \(M\) with \(m_T\geqslant j\). So \[n\,r_{n+1}=\sum_{T}\sum_{j\geqslant1}|T|\;r_{n-j|T|+1}=\sum_{k=1}^n\Big(\sum_{d\mid k}d\,r_d\Big)r_{n-k+1},\] where \(k=jd\) and \(r_d\) counts the tree types \(T\) of size \(d\).
The values are \(1,1,2,4,9,20,48,115,286,719,\ldots\); the recurrence computes \(r_{100}\) instantly.
Theorem 4.5.3 (Otter, 1948). For every tree, the number of orbits of its automorphism group on vertices minus the number of orbits on edges equals \(1\), except when the tree has a symmetry edge, an edge whose ends are swapped by an automorphism; then the difference is \(0\). Consequently \[t_n=r_n-\frac12\Big(\sum_{i=1}^{n-1}r_ir_{n-i}-r_{n/2}\Big),\] where \(r_{n/2}=0\) for odd \(n\).
Proof. Sketch. Remove the orbits of leaves repeatedly: each round removes the same number of vertex orbits and edge orbits, until only the centre is left, which is one vertex (difference \(1\)) or one edge (difference \(1\), or \(0\) if its ends are swapped).
Now add the identity over all trees with \(n\) vertices. The vertex orbits of all trees are the rooted trees: \(r_n\) in all. The edge orbits are the trees with a marked edge; cutting the marked edge gives an unordered pair of rooted trees with sizes adding up to \(n\), and there are \(\frac12\big(\sum r_ir_{n-i}+r_{n/2}\big)\) such pairs. The trees with a symmetry edge correspond to the pairs of two equal rooted trees, \(r_{n/2}\) of them. So \(t_n=r_n-\frac12\big(\sum r_ir_{n-i}+r_{n/2}\big)+r_{n/2}\).
The values of \(t_n\) for \(n=1,\ldots,12\) are \(1,1,1,2,3,6,11,23,47,106,235,551\).
Richard Otter’s paper The number of trees (Annals of Mathematics, 1948) also found the asymptotic growth \(t_n\sim C\alpha^nn^{-5/2}\) with \(\alpha=2.9557\ldots\), a result of the kind studied in Chapter 6. The constant \(\alpha\) is still known only numerically.
Bounding the height keeps the recursion finite in another way. Let \(r^{(h)}_n\) be the number of rooted trees with \(n\) vertices and height at most \(h\) (every vertex at distance at most \(h\) from the root). Removing the root leaves a multiset of rooted trees of height at most \(h-1\), and the argument of Theorem 4.5.2 gives \[r^{(h)}_{n+1}=\frac1n\sum_{k=1}^n\Big(\sum_{d\mid k}d\,r^{(h-1)}_d\Big)r^{(h)}_{n-k+1}.\] For \(h=1\) the trees are stars, and for \(h=2\) a tree is a multiset of stars, so \(r^{(2)}_{n+1}=p(n)\), the number of partitions of \(n\). Trees of a given diameter are counted from the same numbers, because a tree of diameter \(2h\) is a central vertex with at least two branches of height exactly \(h-1\), and a tree of diameter \(2h+1\) is a central edge with two rooted trees of height exactly \(h\) at its ends.
import networkx as nx
from networkx.generators.nonisomorphic_trees import nonisomorphic_trees
def rooted(N, height=None):
# rooted trees with n vertices, optionally of height <= height
if height == 0:
return [0, 1] + [0] * (N - 1)
sub = rooted(N, None if height is None else height - 1) if height is not None else None
r = [0, 1]
for n in range(1, N):
a = sub if sub is not None else r
s = 0
for k in range(1, n + 1):
c = sum(d * a[d] for d in range(1, k + 1) if k % d == 0 and d < len(a))
s += c * r[n - k + 1]
r.append(s // n)
return r
N = 16
r = rooted(N)
t = [0] + [r[n] - (sum(r[i] * r[n - i] for i in range(1, n)) - (r[n // 2] if n % 2 == 0 else 0)) // 2 for n in range(1, N + 1)]
print("rooted trees:", r[1:])
print("free trees: ", t[1:])
print("check: ", [sum(1 for _ in nonisomorphic_trees(n)) for n in range(2, 12)])
print("height <= 2: ", rooted(12, 2)[1:])
Exercise 4.5.1 Pure
Draw the \(r_5=9\) rooted trees with \(5\) vertices and the \(t_6=6\) trees with \(6\) vertices.
Exercise 4.5.2 Pure
Show that \(r^{(2)}_{n+1}=p(n)\), and compute the number of rooted trees with \(10\) vertices and height at most \(2\).
Exercise 4.5.3 Pure Code
How many trees with \(7\) vertices have diameter \(4\)?
A tree of diameter \(4\) has a central vertex with at least two branches of height exactly \(1\).
Exercise 4.5.4 Math Olympiad
A caterpillar is a tree in which the vertices of degree at least \(2\) form a path. Show that the number of caterpillars with \(n\geqslant4\) vertices is \(2^{n-4}+2^{\lfloor(n-4)/2\rfloor}\), and find the only tree with \(7\) vertices that is not a caterpillar.
Read the degrees along the spine as a composition, up to reversal.
Exercise 4.5.5 Pure
Use Theorem 4.5.3 to compute \(t_{10}\) from \(r_1,\ldots,r_{10}\).
Exercise 4.5.6 Computer Science Algorithm
Describe an algorithm that lists all unlabeled trees with \(n\) vertices, each exactly once, with constant time per tree on average. (Look up the algorithm of Wright, Richmond, Odlyzko and McKay, 1986.)
Exercise 4.5.7 Research Project
A project: alkanes. An alkane \(C_nH_{2n+2}\) corresponds to a tree with \(n\) vertices and maximum degree at most \(4\) (the carbon skeleton).
Many of the triangles of numbers in this book obey a recurrence of one and the same shape: \[a(n,k)=f(n,k)\,a(n-1,k-1)+g(n,k)\,a(n-1,k),\qquad a(0,0)=1,\] with \(a(n,k)=0\) unless \(0\leqslant k\leqslant n\). The binomial coefficients have \(f=g=1\); the Stirling numbers \(S(n,k)\) have \(f=1\), \(g=k\); the unsigned Stirling numbers of the first kind \(c(n,k)\) have \(f=1\), \(g=n-1\). We call such triangles Stirling-like. This section collects a simple matrix tool for them and shows where they come from in graphs.
| triangle | \(f(n,k)\) | \(g(n,k)\) | counts |
|---|---|---|---|
| \(\binom nk\) | \(1\) | \(1\) | \(k\)-subsets of \([n]\) |
| \(S(n,k)\) | \(1\) | \(k\) | partitions of \([n]\) into \(k\) blocks |
| \(c(n,k)\) | \(1\) | \(n-1\) | permutations of \([n]\) with \(k\) cycles |
| \(L(n,k)\) (Lah) | \(1\) | \(n+k-1\) | partitions of \([n]\) into \(k\) ordered lists |
| Eulerian \(A(n,k)\) | \(n-k\) | \(k+1\) | permutations of \([n]\) with \(k\) ascents |
Write the \(n\)th row as a vector \(R_n=\big(a(n,0),\ldots,a(n,n)\big)\). The recurrence says \(R_n=R_{n-1}M_n\), where \(M_n\) is the \(n\times(n+1)\) matrix with \(g(n,k)\) in position \((k,k)\), \(f(n,k+1)\) in position \((k,k+1)\), and zeros elsewhere. So the whole triangle is a product of bidiagonal matrices, \[R_n=M_1M_2\cdots M_n,\] in the same way as the Fibonacci numbers are the entries of a power of \(\begin{pmatrix}1&1\\1&0\end{pmatrix}\). Two special shapes give closed identities.
Theorem 4.6.1. Suppose \(f=1\) and \(g(n,k)=c_k\) depends only on \(k\). Put \(P_k(x)=(x-c_0)(x-c_1)\cdots(x-c_{k-1})\). Then for every \(n\geqslant0\) \[x^n=\sum_{k=0}^na(n,k)\,P_k(x).\] In other words, the triangle is the matrix that changes the basis \(\{x^n\}\) of the polynomials into the basis \(\{P_k(x)\}\).
Proof. Induction on \(n\), the case \(n=0\) being \(1=P_0\). Since \(xP_k(x)=P_{k+1}(x)+c_kP_k(x)\), \[x^n=x\sum_ka(n-1,k)P_k(x)=\sum_ka(n-1,k)\big(P_{k+1}(x)+c_kP_k(x)\big)=\sum_k\big(a(n-1,k-1)+c_ka(n-1,k)\big)P_k(x).\]
Theorem 4.6.2. Suppose \(f=1\) and \(g(n,k)=d_n\) depends only on \(n\). Then \[\sum_{k=0}^na(n,k)\,x^k=(x+d_1)(x+d_2)\cdots(x+d_n).\]
Proof. \(\sum_ka(n,k)x^k=\sum_k\big(a(n-1,k-1)+d_na(n-1,k)\big)x^k=(x+d_n)\sum_ka(n-1,k)x^k\).
With \(c_k=k\), Theorem 4.6.1 is the identity \(x^n=\sum_kS(n,k)x^{\underline k}\); with \(c_k=1\) it is the binomial theorem for \(x=(x-1)+1\). With \(d_n=n-1\), Theorem 4.6.2 is \(x(x+1)\cdots(x+n-1)=\sum_kc(n,k)x^k\). Since the change-of-basis matrices compose, so do the triangles: the Lah triangle is the product of the matrices \(\big(c(n,j)\big)\) and \(\big(S(j,k)\big)\), because \(x(x+1)\cdots(x+n-1)=\sum_jc(n,j)x^j=\sum_kL(n,k)\,x^{\underline k}\).
Definition 4.6.3. For a graph \(G\), let \(S(G,k)\) be the number of partitions of \(V(G)\) into \(k\) non-empty independent sets, and let \(B(G)=\sum_kS(G,k)\), the Bell number of \(G\).
For the empty graph \(\overline{K_n}\) these are \(S(n,k)\) and the Bell number \(B_n\). In general, a proper colouring with colours \(1,\ldots,x\) is a partition into independent sets together with distinct colours for the blocks, so \[P(G,x)=\sum_kS(G,k)\,x^{\underline k},\] and Theorem 4.1.3 becomes \(S(G,k)=S(G-e,k)-S(G/e,k)\), a recurrence on graphs rather than on \(n\).
Proposition 4.6.4. For the path \(P_n\), \(S(P_n,k)=S(n-1,k-1)\), and these numbers satisfy the Stirling-like recurrence \(S(P_n,k)=S(P_{n-1},k-1)+(k-1)\,S(P_{n-1},k)\). In particular \(B(P_n)=B_{n-1}\).
Proof. Let the path be \(1,2,\ldots,n\). In a partition into independent sets, vertex \(n\) is either alone, or joins one of the \(k-1\) blocks not containing \(n-1\); this gives the recurrence. The recurrence of \(S(n-1,k-1)\) is the same, with the same initial values.
For cycles there is no such simple recurrence, but a surprise: the Bell numbers \(B(C_n)\) for \(n=3,4,\ldots\) are \(1,4,11,41,162,715\), the numbers of partitions of \([n]\) with no singleton block. For the Petersen graph \(B=7430\).
From the authors’ research
D. Yaqubi and M. Mirzavaziri, Stirling-like sequences and a matrix tool (title to be confirmed) · in preparation
[Authors: summarise in three or four sentences the class of triangles you study, the matrix tool (how it generalises the bidiagonal products above), the identities it proves, and the application you have in mind. Add the preprint link when it exists.]
from fractions import Fraction
from math import comb
import networkx as nx
from sympy.utilities.iterables import multiset_partitions
def triangle(f, g, N):
a = [[1]]
for n in range(1, N + 1):
prev = a[-1] + [0]
row = [(f(n, k) * prev[k - 1] if k >= 1 else 0) + g(n, k) * prev[k] for k in range(n + 1)]
a.append(row)
return a
S = triangle(lambda n, k: 1, lambda n, k: k, 8)
c = triangle(lambda n, k: 1, lambda n, k: n - 1, 8)
L = triangle(lambda n, k: 1, lambda n, k: n + k - 1, 8)
print("S(7,k):", S[7])
print("c(7,k):", c[7])
print("L(7,k):", L[7])
# Lah = c * S as matrices
print("check L = c S:", all(L[n][k] == sum(c[n][j] * S[j][k] for j in range(k, n + 1)) for n in range(9) for k in range(n + 1)))
def graph_stirling(G):
V, out = list(G), {}
for p in multiset_partitions(V):
if all(not G.has_edge(u, v) for blk in p for u in blk for v in blk if u != v):
out[len(p)] = out.get(len(p), 0) + 1
return [out.get(k, 0) for k in range(1, len(V) + 1)]
for n in range(3, 9):
row = graph_stirling(nx.cycle_graph(n))
print("C_%d" % n, row, "B =", sum(row))
print("Petersen", graph_stirling(nx.petersen_graph()), "B =", sum(graph_stirling(nx.petersen_graph())))
Exercise 4.6.1 Pure
Show that \(S(K_{1,n},k)=S(n,k-1)\) and \(B(K_{1,n})=B_n\).
Exercise 4.6.2 Pure
Prove that \(B(C_n)\) equals the number of partitions of \([n]\) with no singleton block.
Deletion–contraction gives \(S(C_{n+1},k)+S(C_n,k)=S(P_{n+1},k)\), so \(B(C_{n+1})+B(C_n)=B_n\) by Proposition 4.6.4.
A partition of \([n]\) either has no singleton block, or merging all its singleton blocks together with \(n+1\) into one block gives a partition of \([n+1]\) without singletons. Show that this is a bijection onto all partitions of \([n+1]\) without singletons.
Exercise 4.6.3 Pure
Show that the Lah numbers are \(L(n,k)=\binom{n-1}{k-1}\frac{n!}{k!}\), and check the recurrence \(L(n,k)=L(n-1,k-1)+(n+k-1)L(n-1,k)\).
Exercise 4.6.4 Pure
The Eulerian numbers do not have \(f=1\). Prove the recurrence \(A(n,k)=(n-k)A(n-1,k-1)+(k+1)A(n-1,k)\) by inserting \(n\) into a permutation of \([n-1]\), and prove Worpitzky’s identity \(x^n=\sum_kA(n,k)\binom{x+k}n\).
Exercise 4.6.5 Code
Compute \(B(G)\) for the Petersen graph.
Exercise 4.6.6 Research Project
A project: Stirling-like triangles from graph families. For a family \(G_n\) (paths, stars, cycles, \(K_n\) minus a perfect matching, …), look at the triangle \(S(G_n,k)\).
We end the chapter with a counting problem that has no known recurrence, and with the beginning of a research programme around it.
Definition 4.7.1. A Latin square of order \(n\) is an \(n\times n\) array filled with the symbols \(1,\ldots,n\) so that each symbol occurs exactly once in every row and every column. Let \(L_n\) be the number of Latin squares of order \(n\).
A Latin square is a graph-theoretic object in disguise. Take \(K_{n,n}\) with rows \(r_1,\ldots,r_n\) on one side and columns \(c_1,\ldots,c_n\) on the other, and colour the edge \(r_ic_j\) with the symbol in cell \((i,j)\). The Latin condition says exactly that edges of the same colour never meet: a Latin square of order \(n\) is a proper edge colouring of \(K_{n,n}\) with colours \(1,\ldots,n\), and each colour class is a perfect matching.
Euler studied Latin squares in 1782 in connection with his problem of the 36 officers, and Ronald Fisher made them a basic tool of the design of agricultural experiments in the 1920s. Brendan McKay and Ian Wanless computed \(L_{11}\) in 2005; \(L_{12}\) is still unknown.
The values are \(L_1,\ldots,L_7=1,\ 2,\ 12,\ 576,\ 161\,280,\ 812\,851\,200,\ 61\,479\,419\,904\,000\). Permuting the rows and the columns, one may assume that the first row and the first column read \(1,2,\ldots,n\); such squares are reduced, and \(L_n=n!\,(n-1)!\,R_n\) with \(R_1,\ldots,R_7=1,1,1,4,56,9408,16\,942\,080\).
A \(k\times n\) Latin rectangle (\(k\leqslant n\)) has \(k\) rows with the same conditions. The number of \(2\times n\) Latin rectangles is \(n!\,D_n\): the first row is any permutation and the second is a derangement relative to it. For \(k=3\) a formula with a single sum is known (Riordan, 1944), and beyond that nothing of the kind.
Theorem 4.7.2. Every \(k\times n\) Latin rectangle with \(k<n\) can be extended by a row. Moreover \[\frac{(n!)^{2n}}{n^{n^2}}\ \leqslant\ L_n\ \leqslant\ \prod_{k=1}^n(k!)^{n/k},\] and consequently \(L_n=\big((1+o(1))\,n/e^2\big)^{n^2}\).
Proof. Let \(H\) be the bipartite graph between the \(n\) columns and the \(n\) symbols, with column \(j\) joined to the symbols not yet used in column \(j\). Each column misses \(n-k\) symbols, and each symbol, having been used once in each of the \(k\) rows, misses \(n-k\) columns; so \(H\) is \((n-k)\)-regular. A new row is exactly a perfect matching of \(H\), and a regular bipartite graph has one, by Hall’s theorem (Chapter 7).
The number of perfect matchings of \(H\) is the permanent of its \(0/1\) matrix. By the van der Waerden bound (proved by Egorychev and Falikman, 1981), the permanent of an \(r\)-regular \(n\times n\) \(0/1\) matrix is at least \(n!\,(r/n)^n\); by Brègman’s theorem (1973) it is at most \((r!)^{n/r}\). Multiplying over \(k=0,\ldots,n-1\), that is over \(r=n,\ldots,1\), gives the two bounds, and Stirling’s formula gives the asymptotics.
So we know \(\log L_n\) to within a factor \(1+o(1)\), but not \(L_n\) itself, and no recurrence in \(n\) is known. One way to look for structure is to refine the count.
Definition 4.7.3. Read each column of a Latin square from top to bottom; it is a permutation of \([n]\), and it has some number of ascents (positions where the next entry is larger). For \(\mathbf k=(k_1,\ldots,k_n)\) let \(\mathrm{LE}_n(\mathbf k)\) be the number of Latin squares of order \(n\) whose \(j\)th column has exactly \(k_j\) ascents, for every \(j\). These are the Latin Eulerian numbers.
Proposition 4.7.4. (a) \(\mathrm{LE}_n(\mathbf k)\) does not change when the entries of \(\mathbf k\) are permuted.
\(\mathrm{LE}_n(k_1,\ldots,k_n)=\mathrm{LE}_n(n-1-k_1,\ldots,n-1-k_n)\).
For each \(k\), the number of Latin squares whose first column has \(k\) ascents is \(A(n,k)\,L_n/n!\), where \(A(n,k)\) is the Eulerian number.
\(\sum_{\mathbf k}\mathrm{LE}_n(\mathbf k)=L_n\).
Proof. (a) Permuting the columns of a square permutes the vector of ascents. (b) Replace every symbol \(s\) by \(n+1-s\); an ascent of a column becomes a descent. (c) Permuting the rows by \(\pi\) is a bijection on Latin squares that changes the first column \(w\) into \(w\circ\pi^{-1}\); so every permutation occurs as the first column of exactly \(L_n/n!\) squares, and \(A(n,k)\) of these permutations have \(k\) ascents. (d) is clear.
Example 4.7.5. For \(n=3\) each of the six vectors \((0,1,1)\), \((1,0,1)\), \((1,1,0)\), \((1,1,2)\), \((1,2,1)\), \((2,1,1)\) occurs for exactly \(2\) of the \(12\) squares, and no other vector occurs. For \(n=4\), \(54\) different vectors occur; the most frequent are the six rearrangements of \((1,1,2,2)\), each occurring \(64\) times, which together account for \(384\) of the \(576\) squares.
From the authors’ research
D. Yaqubi and M. Mirzavaziri, Latin Eulerian Numbers (title to be confirmed) · in preparation
[Authors: summarise the main results of the paper: the definition and notation you use, the local-switching technique for comparing balanced and unbalanced vectors \(\mathbf k\), any formulas or recurrences, and the planned companion papers on cyclic Latin Eulerian numbers and Latin Eulerian polynomials. Add the preprint link when it exists.]
import itertools as it
from collections import Counter
from math import factorial
def latin_squares(n):
rows = list(it.permutations(range(1, n + 1)))
out = []
def extend(square):
if len(square) == n:
out.append(square); return
for r in rows:
if all(r[j] != s[j] for s in square for j in range(n)):
extend(square + [r])
extend([])
return out
def ascents(col):
return sum(1 for i in range(len(col) - 1) if col[i] < col[i + 1])
for n in range(1, 6):
Ls = latin_squares(n)
reduced = sum(1 for s in Ls if s[0] == tuple(range(1, n + 1)) and tuple(r[0] for r in s) == tuple(range(1, n + 1)))
print(f"n = {n}: L_n = {len(Ls)}, reduced = {reduced}, n!(n-1)!R_n = {factorial(n) * factorial(n - 1) * reduced}")
if n <= 4:
LE = Counter(tuple(ascents([r[j] for r in s]) for j in range(n)) for s in Ls)
types = Counter()
for k, v in LE.items():
types[tuple(sorted(k))] += v
print(" by multiset of ascent numbers:", dict(sorted(types.items())))
Research thread · Is there a recurrence for Latin squares?
No recurrence for \(L_n\) is known, and none is expected to be simple: \(L_n\) is known only for \(n\leqslant11\). The refinement by ascents is one attempt to find hidden structure. Some natural questions: is \(\mathrm{LE}_n(\mathbf k)\) largest when the \(k_j\) are as equal as possible (as for \(n=4\))? What is the distribution of the total number of ascents \(k_1+\cdots+k_n\), and is it asymptotically normal? Is there a recurrence for the squares whose columns all have the minimum possible number of ascents? Compute the \(161\,280\) squares of order \(5\) and test your guesses.
Reading: B. D. McKay and I. M. Wanless, On the number of Latin squares, Ann. Comb. 9 (2005); J. H. van Lint and R. M. Wilson, A Course in Combinatorics, Chapter 17.
Exercise 4.7.1 Pure
Prove that \(L_n=n!\,(n-1)!\,R_n\).
Permute the columns so that the first row reads \(1,\ldots,n\); this permutation is unique. Then permute the rows other than the first so that the first column reads \(1,\ldots,n\); this is unique too.
Exercise 4.7.2 Pure
Count the \(2\times5\) Latin rectangles.
Exercise 4.7.3 Math Olympiad
Let a Latin square of odd order \(n\) be symmetric about its main diagonal. Prove that every symbol occurs exactly once on the diagonal.
Off the diagonal, each symbol occurs an even number of times.
Exercise 4.7.4 Pure
Show that the Latin squares of order \(n\) correspond to the decompositions of the complete tripartite graph \(K_{n,n,n}\) into \(n^2\) triangles, with the three parts labelled.
Exercise 4.7.5 Code
Compute the Latin Eulerian numbers for \(n=5\) and find the most frequent multiset of ascent numbers.
Exercise 4.7.6 Pure
Use (c) of Proposition 4.7.4 to show that the average number of ascents in a column of a random Latin square of order \(n\) is \((n-1)/2\).
Exercise 4.7.7 Research Project
A project: the total number of ascents. Let \(T\) be the total number of ascents \(k_1+\cdots+k_n\) of a random Latin square of order \(n\), all squares being equally likely.
adjacency matrix. The \(n\times n\) matrix \(A\) of a graph on \([n]\) with \(a_{uv}=1\) when \(uv\) is an edge and \(a_{uv}=0\) otherwise. Wikipedia · MathWorld
arborescence. A directed spanning tree in which every vertex except the root has exactly one outgoing arc and all arcs lead towards the root (or, in the other convention, away from it). Wikipedia · MathWorld
automorphism. An isomorphism from a graph to itself. The automorphisms form the group \(\mathrm{Aut}(G)\). Wikipedia · MathWorld
Bell number. \(B_n\), the number of partitions of an \(n\)-set; also the number of cluster graphs on \([n]\). Wikipedia · MathWorld
bijection. A one-to-one and onto map. Two finite sets have the same size exactly when there is a bijection between them. Wikipedia · MathWorld
bipartite graph. A graph whose vertices split into two sets so that every edge joins the two sets; equivalently, a graph with no odd cycle. Wikipedia · MathWorld
Catalan number. \(\mathrm{Cat}_n=\frac1{n+1}\binom{2n}n\); counts binary plane trees and triangulations of polygons. Wikipedia · MathWorld
chromatic polynomial. \(P(G,k)\), the number of proper colourings of \(G\) with \(k\) colours; a polynomial in \(k\). Wikipedia · MathWorld
complement. The graph on the same vertices whose edges are exactly the non-edges of \(G\). Wikipedia · MathWorld
complete graph. The graph \(K_n\) on \(n\) vertices in which every two vertices are adjacent. Wikipedia · MathWorld
composition. An ordered sequence of positive integers with sum \(n\). Wikipedia
connected component. A maximal connected subgraph. The components partition the vertex set. Wikipedia · MathWorld
cycle. A closed walk of length at least \(3\) whose vertices, apart from the first and last, are distinct. Wikipedia · MathWorld
cycle index. The average over a permutation group of the monomials recording the cycle lengths of its elements. Wikipedia · MathWorld
degree. The number of edges at a vertex. In a simple graph it equals the number of neighbours. Wikipedia · MathWorld
directed graph. A graph whose edges, called arcs, have a direction from a tail to a head. Wikipedia · MathWorld
distinguishing colouring. A vertex colouring preserved by no non-trivial automorphism; the least number of colours needed is the distinguishing number. Wikipedia · MathWorld
double counting. Counting one set in two different ways and equating the results. Wikipedia
graceful labeling. A labeling of the vertices of a graph with \(m\) edges by distinct integers from \(0\) to \(m\) such that the edge differences \(|a-b|\) are exactly \(1,2,\ldots,m\). Wikipedia · MathWorld
graph. A pair \((V,E)\) of a set of vertices and a set of edges, each edge joining two vertices. Wikipedia · MathWorld
group action. A rule by which each element of a group permutes a set, compatibly with the group operation. Wikipedia · MathWorld
hypercube. The graph \(Q_n\) on binary words of length \(n\), two words being adjacent when they differ in one position. Wikipedia · MathWorld
induced subgraph. For a vertex set \(U\), the subgraph \(G[U]\) with vertex set \(U\) and all edges of \(G\) inside \(U\). Wikipedia · MathWorld
isomorphism. A bijection between vertex sets that preserves adjacency and non-adjacency. Wikipedia · MathWorld
labeled tree. A tree whose vertices carry distinct names, usually \(1,2,\ldots,n\). Two labeled trees are equal only if they have exactly the same edges, so isomorphic trees may still be different labeled trees. Wikipedia · MathWorld
Laplacian matrix. \(L=D-A\), the degree matrix minus the adjacency matrix. Its reduced determinants count spanning trees. Wikipedia · MathWorld
leaf. A vertex of degree 1 in a tree. Every tree with at least two vertices has at least two leaves. Wikipedia · MathWorld
matching. A set of edges no two of which share an end; perfect if it covers every vertex. Wikipedia · MathWorld
multinomial coefficient. The number of words of length \(m\) that use letter \(i\) exactly \(k_i\) times: \(m!/(k_1!\,k_2!\cdots k_r!)\). Wikipedia · MathWorld
necklace. An equivalence class of words of length \(n\) under rotation; a bracelet also allows reflection. Wikipedia · MathWorld
orbit. The set of all images of an element under the elements of a group acting on a set. Wikipedia · MathWorld
partition. A way of writing \(n\) as a sum of positive integers, order disregarded; \(p(n)\) counts them. Wikipedia
path. A walk with no repeated vertex; also the graph \(P_n\) with vertices \(1,\ldots,n\) and edges \(\{i,i+1\}\). Wikipedia · MathWorld
Petersen graph. The \(3\)-regular graph on the \(2\)-subsets of \([5]\), two subsets being adjacent when disjoint. Wikipedia · MathWorld
Pfaffian. A polynomial in the entries of a skew-symmetric matrix of even order whose square is the determinant; a signed sum over perfect matchings. Wikipedia · MathWorld
plane partition. An array of non-negative integers that is weakly decreasing along rows and down columns; a pile of cubes in a corner. Wikipedia · MathWorld
Prüfer sequence. The word of length \(n-2\) obtained from a labeled tree by repeatedly deleting the smallest leaf and recording its neighbour. Wikipedia · MathWorld
rooted tree. A tree with one distinguished vertex, the root. Edges can then be oriented towards the root. Wikipedia · MathWorld
spanning tree. A subgraph of \(G\) that contains every vertex of \(G\) and is a tree. Wikipedia · MathWorld
Stirling number of the second kind. \(S(m,j)\) is the number of ways to partition an \(m\)-element set into \(j\) non-empty blocks. Wikipedia · MathWorld
tournament. An orientation of a complete graph: every two vertices are joined by exactly one arc. Wikipedia · MathWorld
tree. A connected graph with no cycles. A tree on \(n\) vertices has exactly \(n-1\) edges. Wikipedia · MathWorld
walk. A sequence of vertices in which consecutive vertices are adjacent. A trail repeats no edge; a path repeats no vertex. Wikipedia