148 Matchings
148.1 Matchings
Mathlib supplies "matching" (Subgraph.IsMatching), "saturates" (v \(\in \) M.verts) and "perfect" (Subgraph.IsPerfectMatching), but has no matching-number notion, so maximality has to be said by hand:
M.IsMatching \(\land \) \(\forall \) M’, M’.IsMatching \(\to \) M’.edgeSet.ncard \(\le \) M.edgeSet.ncard
This is a global maximum, not a maximal matching (one admitting no extension). The two genuinely differ, and Berge’s Theorem 5.1 is exactly the tool that certifies the global property from a local check.
Walk along the graph using a matching edge, then a non-matching edge, then a matching edge, and so on. Rendered as a chain condition on consecutive edges:
List.IsChain (fun e f => e \(\in \) M.edgeSet \(\leftrightarrow \) f \(\notin \) M.edgeSet) p.edges
! Mathlib’s SimpleGraph.IsAlternating (Matching.lean) is a graph-level relation between two graphs and is not this notion; do not reach for it.
Note the definition is on a Walk, not a Path — the book’s "path" is imposed separately in IsAugmenting below via p.IsPath.
Alternating paths are the mechanism by which a matching improves: swapping which edges along such a path belong to \(M\) keeps \(M\) a matching.
An alternating path both of whose endpoints are still unmatched. Such a path has odd length and begins and ends with non-matching edges, so it holds one more non-\(M\) edge than \(M\) edge. Flipping the roles along it — discarding its \(M\)-edges, adopting its non-\(M\)-edges — yields a matching one edge larger, which is why it is called augmenting.
! The conjunct \(u \ne v\) is load-bearing and has no counterpart in the book’s wording. Without it Walk.nil at an \(M\)-unsaturated vertex would satisfy every other clause vacuously, so every non-perfect matching would admit an "augmenting path" and Berge’s theorem would be false in the (\(\Leftarrow \)) direction. The book gets this for free because a path in its sense has at least one edge.
Watch every edge using as few vertices as possible. As with Subgraph.IsMaximumMatching, minimality is spelled out by hand since Mathlib has no covering-number notion.
Keep every vertex, and select edges so each vertex retains exactly \(k\). A \(1\)-factor is precisely a perfect matching; a \(2\)-factor is a spanning union of disjoint cycles.
Degree is written (H.neighborSet v).ncard rather than H.degree v — equal in value, but avoiding the Fintype/DecidableRel instance juggling that Subgraph.degree would drag in on every use.
The edges of \(G\) partition into groups, each a \(k\)-regular spanning subgraph. The book’s \(G = H_{1} \cup \dots \cup H_n\) becomes \((\bigsqcup i, H i) = \top \) in the Subgraph lattice, where \(\top \) is \(G\) viewed as a subgraph of itself.
Being \(1\)-factorable means the edges split into perfect matchings: \(K_{n,n}\) and \(K_{2n}\) are (exercise 5.1.5(a)(i)), the Petersen graph is not (exercise 5.1.5(a)(ii)).
\(1\)-factorability is exactly proper edge colouring with \(\Delta \) colours: each factor is a colour class. So exercise 5.1.5(a)(ii) is the statement that the Petersen graph has chromatic index \(4\), which reappears in EdgeColourings.lean.
The corners and edges of a \(k\)-dimensional cube: \(k\)-regular, bipartite (split by the parity of the number of \(1\)s), \(2^k\) vertices, \(k\cdot 2^{k-1}\) edges.
Adjacency is the book’s condition literally: \(\exists ! i, x i \ne y i\).
! Note this file defines cube directly as a structure, whereas GraphsAndSubgraphs.lean defines the same graph as SimpleGraph.fromRel (fun x y => \(\exists \)! i, x i \(\ne \) y i). The two are equal but not definitionally so, and neither imports the other.
Vertices are the squares of an \(m \times n\) board, adjacent when they share a side. A perfect matching is exactly a tiling by \(1 \times 2\) dominoes, since each domino covers precisely one side-adjacent pair.
Adjacency is spelled out coordinatewise: same row and columns differing by one, or same column and rows differing by one. Written on \(\mathbb {N}\) values (p.2.val + 1 = q.2.val) rather than on Fin arithmetic, which would wrap around and wrongly join the last column to the first.
Both directions are stated contrapositively relative to the book’s phrasing: the Lean \(\leftrightarrow \) has "no augmenting path" on the right, so the book’s first paragraph proves (\(\Rightarrow \)) by contraposition and its second proves (\(\Leftarrow \)) by contraposition.
Augmenting paths are simultaneously the certificate of non-maximality and the means of improvement — which is what makes the Hungarian method of §5.4 work.
Hall’s condition: no set of vertices on the \(X\) side may collectively have too few neighbours. Colloquially — no group of \(k\) workers may be jointly qualified for fewer than \(k\) jobs.
\(N(S)\) is written \(\bigcup \) v \(\in \) S, G.neighborSet v, and the inequality is stated as S.ncard \(\le \) (\(\bigcup \) …).ncard — the book’s \(|N(S)| \ge |S|\) with sides swapped.
Two applications of double counting, then Hall. The book’s colourful restatement, from which the name comes (§5.2, p. 81):
The edges of a matching are pairwise disjoint and the covering must contain an endpoint of each; since no two matching edges share an endpoint, the chosen endpoints are distinct, so \(K\) has at least \(|M|\) elements.
The book continues:
which is König’s Theorem 5.3.
The standard "weak duality certifies optimality" argument: exhibiting a matching and a covering of the same size proves both optimal at once. It is exactly how Theorem 5.3 is proved.
The prototypical min-max theorem of combinatorics — maximum packing equals minimum cover. Closely related to Hall’s theorem: exercise 5.2.7 asks to derive Hall from König, and its matrix form is exercise 5.2.5.
Note the Lean statement takes both extremal objects as hypotheses (hM, hK) and concludes their sizes agree, rather than constructing \(\tilde{K}\) as the book does.
The obstruction to a perfect matching is a set \(S\) whose removal leaves more odd pieces than \(S\) has vertices — each odd piece must "export" a vertex to be matched into \(S\).
A double count per odd component, then Tutte. The parity step is the crux: \(m_{i} = 3\nu (G_{i}) - 2\varepsilon (G_{i})\) is odd because \(\nu (G_{i})\) is odd, and bridgelessness then upgrades \(m_{i} \ge 1\) to \(m_{i} \ge 3\).
! The book’s \(\tfrac {1}{3} \sum m_{i} \le \tfrac {1}{3} \sum _{v \in S} d(v)\) is over \(\mathbb {Q}\). In \(\mathbb {N}\) this should be cleared to \(3n \le \sum m_{i} \le 3|S|\) and divided only at the end, or done in \(\mathbb {Z}\).
Assign a label to every vertex so the two labels at an edge’s ends sum to at least its weight. Weights are carried as w : Sym2 V \(\to \) \(\mathbb {R}\) rather than \(V \to V \to \mathbb {R}\), which makes symmetry automatic.
Labels are the dual objects to matchings: \(\sum _v l(v)\) upper-bounds the weight of any perfect matching, and Theorem 5.5 says a matching attaining that bound is optimal.
! The existence claim (5.12) is not stated as a lemma anywhere in this file, though the Kuhn–Munkres algorithm needs it as its starting point.
Keep only the edges that are "tight" for the labelling — those whose weight exactly uses up the sum of the labels at their ends. As the Kuhn–Munkres algorithm adjusts labels the equality subgraph changes, and the algorithm stops once some equality subgraph contains a perfect matching.
Representing weights as Sym2 V \(\to \) \(\mathbb {R}\) makes \(l x + l y = w s(x,y)\) symmetric in \(x, y\) definitionally, which is why the symm obligation is routine.
\(\sum ^{f}\) e \(\in \) M.edgeSet, w e, using the finsum \(\sum ^{f}\) rather than Finset.sum so that no Fintype (M.edgeSet) instance has to be threaded through — M.edgeSet is a Set, and finsum handles the finiteness side condition implicitly.
In the personnel-assignment setting \(w(x_{i}y_{j})\) is the effectiveness of worker \(X_{i}\) in job \(Y_{j}\), and \(w(M)\) the total effectiveness of assignment \(M\).
Among all assignments of each worker to a distinct job, the one of greatest total effectiveness. Maximality is spelled out by hand, as with Subgraph.IsMaximumMatching.
Weak duality certifying optimality again: \(\sum _v l(v)\) bounds every perfect matching from above, and one attaining the bound must be best. This is the foundation of the Kuhn–Munkres algorithm, which alternates the Hungarian method inside \(G_l\) with label adjustments that grow \(G_l\).
The conclusion transports \(M\) along Hom.ofLE from equalitySubgraph w G l up to \(G\), since the two live over different graphs.
The \(k\)-cube is \(k\)-regular and bipartite (sides given by the parity of the number of \(1\)s), so for \(k \ge 2\) Corollary 5.2 applies.
A perfect matching of \(K_{2n}\) partitions \(2n\) labelled objects into \(n\) unordered pairs. Lining them up gives \((2n)!\) arrangements; each matching arises from \(2^n \cdot n!\) of them (swap within each pair, permute the pairs). So the count is \((2n)! / (2^n \cdot n!)\), the double factorial \((2n-1)!! = 1 \cdot 3 \cdot 5 \cdots (2n-1)\).
! The Lean statement uses natural-number division. It happens to be exact here, but the proof cannot manipulate it as division — it must establish Nat.card … (2 ^ n n !) = (2 * n)! and then divide, or the Nat.div will obstruct every rewrite.
Every vertex of \(X\) may be matched to any vertex of \(Y\), so a perfect matching is exactly a bijection \(X \to Y\). There are \(n!\) of those.
This is why the optimal assignment problem of §5.5 has \(n!\) candidate solutions and brute force is hopeless — the book makes exactly that point on p. 94.
Suppose a tree had two perfect matchings \(M \ne M'\). Every vertex meets at most one edge of each, so every vertex of \(M \Delta M'\) has degree one or two and its components are alternating paths and even cycles. Both matchings being perfect, no vertex is an endpoint of such a path, so only cycles occur — impossible in an acyclic graph. Hence \(M \Delta M' = \emptyset \).
Label both sides by ZMod n; for each \(i\), let \(H_{i}\) join \(x_a\) to \(y_{a+i}\) for every \(a\). Each \(H_{i}\) is a 1-factor, distinct \(i\) give edge-disjoint matchings, and every edge \(x_a y_b\) occurs in exactly the one with \(i = b - a\).
In chapter 6’s language: \(K_{n,n}\) has chromatic index \(n\), its minimum possible value — the round-robin schedule for \(n\) workers and \(n\) jobs.
The classical round-robin schedule. Fix one vertex at the centre and arrange the other \(2n - 1\) in a circle. In round \(i\), match the centre with circle vertex \(i\) and pair the remaining circle vertices symmetrically about the line through it. Rotating gives \(2n - 1\) rounds, each a perfect matching, together using every edge exactly once.
So \(2n\) players can be scheduled in \(2n - 1\) rounds with every pair meeting once. This fails for odd order, where no perfect matching exists at all.
\(\delta \ge \nu /2 + 1\) is one better than Dirac’s threshold, so Theorem 4.3 gives a Hamilton cycle \(C\). With \(\nu \) even, \(C\) is an even cycle whose edges split alternately into two perfect matchings. Removing \(C\)’s edges drops every degree by \(2\), leaving enough for a second Hamilton cycle; combining the 2-factor \(C\) with a 1-factor from the second gives degree \(3\) everywhere.
\(\delta \ge \nu /2 + 1\) is formalised as \(\nu + 2 \le 2\delta \) to stay in the natural numbers.
A connected 2-factor is precisely a Hamilton cycle — a spanning connected 2-regular subgraph must be one cycle through every vertex. So this asks for a decomposition of \(K_{2n+1}\)’s edges into Hamilton cycles.
The count works: \(K_{2n+1}\) has \(n(2n+1)\) edges and each Hamilton cycle uses \(2n + 1\), so exactly \(n\) cycles are needed.
The odd-order companion to 5.1.5(a)(i): odd complete graphs decompose into Hamilton cycles, even ones into perfect matchings.
Hall’s Theorem 5.2 gives a matching saturating \(X\) from the condition on subsets of \(X\) alone. Demanding it for all subsets of \(V\) is symmetric in \(X\) and \(Y\), so it yields matchings saturating each side; together these force \(|X| = |Y|\) and a perfect matching.
! hcov : X \(\cup \) Y = Set.univ is required and has no counterpart in the book’s wording, which takes "bipartition" to cover all vertices by definition. Mathlib’s IsBipartiteWith does not, so without hcov the bipartition could miss vertices that no matching could ever saturate.
Corollary 5.2 gives a perfect matching \(M\). Deleting its edges lowers every degree by one, leaving a \((k-1)\)-regular bipartite graph; iterate \(k\) times.
In chapter 6’s language this is \(\chi '(G) = \Delta (G)\) for bipartite graphs — König’s edge-colouring theorem. In scheduling terms, a balanced workload always splits into \(k\) conflict-free rounds.
Every degree is even, so Theorem 4.1 gives each component an Euler tour. Traverse it and orient each edge in the direction of travel; every vertex then has in-degree \(k\) and out-degree \(k\), since the tour enters and leaves it \(k\) times. Build the bipartite "tail/head" double cover, joining tail \(u\) to head \(v\) for each oriented edge \(u \to v\). That graph is \(k\)-regular, hence 1-factorable by part (a); translating each perfect matching back gives a spanning subgraph with one in-edge and one out-edge per vertex — a 2-factor.
König’s Theorem 5.3 in matrix dress. A vertex per row and per column, joining row \(i\) to column \(j\) when A i j = true. Lines covering all the \(1\)s are a vertex covering; \(1\)s no two sharing a line are a matching.
The IsLeast/IsGreatest hypotheses supply the two optima as given, so this statement only has to equate them. "No two in the same line" is rendered as the pair of InjOn conditions on Prod.fst and Prod.snd.
Hall’s theorem says a matching saturating \(X\) exists exactly when \(|S| - |N(S)| \le 0\) for all \(S \subseteq X\). The defect formula quantifies failure: the largest \(|S| - |N(S)|\), the deficiency, is exactly how many vertices of \(X\) a maximum matching must leave unsaturated. Hall is the zero-deficiency case.
Formalised additively as |M| + deficiency = |X| to avoid \(\mathbb {N}\) subtraction on the outside.
! But the inner S.ncard - (\(\bigcup \) …).ncard is still natural subtraction, so it truncates to \(0\) exactly when Hall’s condition holds at \(S\) — which is what makes the \(\bigsqcup \) compute the book’s max{…} correctly only because the book’s max is also effectively taken against \(0\) (via \(S = \emptyset \)). This is a happy accident rather than a faithful rendering, and is worth re-checking when the proof is attempted.
By the defect formula, a maximum matching smaller than \(k\) forces some \(S \subseteq X\) with large \(|S| - |N(S)|\). Every edge meeting \(S\) then ends inside the small set \(N(S)\), and simplicity caps the total edge count at \((k-1)n\) — contradiction.
Equivalently, via König: a covering of size \(\lt k\) caps \(\varepsilon \) at \((k-1)n\), since each covering vertex has degree at most \(n\).
Sum every entry two ways. By rows: \(1\) each, so \(m\) in total. By columns: \(1\) each, so \(n\). Hence \(m = n\).
! Restated, not transcribed. Mathlib’s doublyStochastic is square *by type*, so the literal statement would be vacuous. This version takes a genuinely rectangular Matrix m n \(\mathbb {R}\) with the two summation hypotheses given explicitly, which is what the exercise actually asks.
Note the non-negativity hypothesis is not needed for this part and is omitted.
Left and right cosets each partition \(H\) into \(n = [H : K]\) blocks of size \(|K|\). The claim: one list of \(n\) elements represents both partitions simultaneously.
Hall again — put left cosets on one side, right cosets on the other, joining aK to Kb when they intersect. All cosets having size \(|K|\) makes this graph regular, so Corollary 5.2 gives a perfect matching; choosing an element from each matched intersection is the common transversal.
! The Lean rendering states the two conclusions as Function.Bijective of the maps \(i \mapsto h_{i} \textbullet {} K\) and \(i \mapsto op h_{i} \textbullet {} K\) into Set H. The note in the file flags this shape as provisional, and it is worth scrutiny: bijectivity onto what codomain is left implicit (it is Set H, not the set of cosets), so as written the maps are into a far larger type than intended and the statement may be stronger — or simply wrong — relative to the exercise. Recheck before proving.
Petersen’s argument at general \(k\). For \(S \subset V\) with odd components \(G_{i}\) of \(G - S\) and \(m_{i}\) the edges from \(G_{i}\) to \(S\): regularity gives \(m_{i} = k\nu (G_{i}) - 2\varepsilon (G_{i})\), of the same parity as \(k\nu (G_{i})\). Those edges form an edge cut, so \((k-1)\)-edge-connectivity gives \(m_{i} \ge k - 1\), and parity upgrades that to \(m_{i} \ge k\) where needed. Summing, \(k \cdot o(G - S) \le \sum m_{i} \le \sum _{v \in S} d(v) = k|S|\).
Corollary 5.4 is the case \(k = 3\): a bridgeless cubic graph is 2-edge-connected.
Tutte’s condition quantifies over all \(S\), but for trees the singletons already decide it.
(\(\Rightarrow \)) The partner of \(v\) lies in one component of \(G - v\), and a parity count shows exactly one component is odd.
(\(\Leftarrow \)) \(o(G - v) = 1\) for every \(v\) is Tutte’s condition at singletons, and acyclicity makes that enough: build greedily from the leaves, each leaf forced to match its unique neighbour.
Combined with exercise 5.1.2, a tree’s perfect matching — when it exists — is unique and locally detectable.
Tutte says a perfect matching exists exactly when \(o(G - S) - |S| \le 0\) for all \(S\). Berge’s formula quantifies failure: the maximum, the deficiency \(d\), is exactly how many vertices a maximum matching leaves unsaturated; the remaining \(\nu - d\) pair up.
\(d = 0\) recovers Theorem 5.4. The general-graph analogue of the König–Ore defect formula (5.2.6(a)).
Formalised additively as \(2|M| + d = \nu \) to avoid \(\mathbb {N}\) subtraction on the outside.
! Same caveat as konig_ore_defect: the inner oddComponents.ncard - S.ncard is still natural subtraction and truncates at \(0\). Here that is actually correct, since \(S = \emptyset \) always contributes \(o(G) - 0 \ge 0\) and the book’s max is over a set containing a non-negative value — but it should be re-verified rather than assumed.
An edge-count sufficient condition, in the spirit of Corollary 4.6 for hamiltonicity. The threshold is the edge count of the densest simple graph on \(\nu \) vertices with minimum degree \(\delta \) that still violates Tutte’s condition: a \(\delta \)-set \(S\) whose removal leaves too many odd components, plus as many edges as can be packed around it. Exceeding it leaves no room to violate Tutte.
Part (a) — "characterise the maximal simple graphs which have no perfect matching" — has no propositional content and is dropped; the book’s answer is recorded in the dropped-items section at the end of this file.