Kuhn's Algorithm Computes a Maximum Matching
Lax117284.BipartiteKuhnCorrect · concepts/Lax117284/BipartiteKuhnCorrect.lean · lax-117284
No public endorsements yet.
Loading review…
Sign in with ORCIDNatural Language Statement
Theorem
The matching Kuhn's algorithm returns is a matching of the graph, and no matching of the graph has more edges. In particular it saturates the left side exactly when some matching does, and its size is the matching number of the bipartite graph.
Concept map
Evidence
Lean source view on GitHub
| 1 | import Lax117284.BipartiteKuhn |
| 2 | import Lax117284.BipartiteMatching |
| 3 | import Lax117284.BipartiteGraph |
| 4 | |
| 5 | /-! |
| 6 | --- |
| 7 | title: Kuhn's Algorithm Computes a Maximum Matching |
| 8 | type: theorem |
| 9 | --- |
| 10 | The matching Kuhn's algorithm returns is a matching of the graph, and no matching of the graph |
| 11 | has more edges. In particular it saturates the left side exactly when some matching does, and |
| 12 | its size is the matching number of the bipartite graph. |
| 13 | |
| 14 | # Formalization Notes |
| 15 | |
| 16 | The first two statements are about the relation the algorithm works on; the third is about the |
| 17 | graph, in Mathlib's terms: for a graph on `Fin V` split at `n`, the relation between `Fin n` |
| 18 | and `Fin (V - n)` is adjacency across the split, and a matching of the graph is the same thing |
| 19 | as an injective assignment of left neighbours to right vertices, edge for edge. |
| 20 | |
| 21 | The proof does not use Berge's lemma. A search from `l₀` fails only when every right vertex |
| 22 | reachable from `l₀` by alternating exploration is already matched, and the left vertices so |
| 23 | reached then outnumber the right vertices so reached by exactly one. This state is stable: a |
| 24 | later augmentation from another free vertex keeps the reached left vertices matched, hence into |
| 25 | the same set of right neighbours, which it therefore saturates again, so that `l₀` reaches |
| 26 | nothing new and stays failed. At the end the failed left vertices `F` and the set `S` of all |
| 27 | left vertices reachable from them have `|N(S)| = |S| - |F|`, and any matching matches at most |
| 28 | `|N(S)|` vertices of `S`, so it has at most `|L| - |F|` edges — which is the size of the |
| 29 | matching returned, since every left vertex outside `F` is matched. |
| 30 | -/ |
| 31 | |
| 32 | namespace Lax117284.BipartiteKuhnCorrect |
| 33 | |
| 34 | open Lax117284.BipartiteKuhn Lax117284.BipartiteMatching Lax117284.BipartiteGraph |
| 35 | |
| 36 | variable {L R : Type*} [Fintype L] [DecidableEq L] [Fintype R] [DecidableEq R] |
| 37 | (adj : L → R → Prop) [DecidableRel adj] |
| 38 | |
| 39 | /-- **The result is a matching of the graph.** -/ |
| 40 | axiom kuhn_isMatching : Respects adj (kuhn adj) ∧ InjOnSupport (kuhn adj) |
| 41 | |
| 42 | /-- **No matching is larger.** -/ |
| 43 | axiom kuhn_maximum (μ : R → Option L) (hres : Respects adj μ) (hinj : InjOnSupport μ) : |
| 44 | size μ ≤ size (kuhn adj) |
| 45 | |
| 46 | /-- **A matching saturating the left side exists exactly when the result is one.** -/ |
| 47 | axiom kuhn_saturates_iff : |
| 48 | (∀ l, Matched (kuhn adj) l) ↔ ∃ f : L → R, Function.Injective f ∧ ∀ l, adj l (f l) |
| 49 | |
| 50 | /-- The adjacency across the split of a graph on `Fin V` split at `n`, as a relation between |
| 51 | the left vertices `Fin n` and the right vertices `Fin (V - n)`. -/ |
| 52 | def leftRel {V : ℕ} (G : SimpleGraph (Fin V)) (n : ℕ) (hn : n ≤ V) : |
| 53 | Fin n → Fin (V - n) → Prop := |
| 54 | fun i j => G.Adj ⟨i, by omega⟩ ⟨n + j, by omega⟩ |
| 55 | |
| 56 | open scoped Classical in |
| 57 | /-- **The size of the result is the matching number of the graph.** -/ |
| 58 | axiom kuhn_matchingNumber {V : ℕ} (G : SimpleGraph (Fin V)) (n : ℕ) (hn : n ≤ V) |
| 59 | (hs : SplitAt G n) : size (kuhn (leftRel G n hn)) = matchingNumber G |
| 60 | |
| 61 | end Lax117284.BipartiteKuhnCorrect |
| 62 |
Formalization Notes
The first two statements are about the relation the algorithm works on; the third is about the graph, in Mathlib's terms: for a graph on split at , the relation between and is adjacency across the split, and a matching of the graph is the same thing as an injective assignment of left neighbours to right vertices, edge for edge.
The proof does not use Berge's lemma. A search from fails only when every right vertex reachable from by alternating exploration is already matched, and the left vertices so reached then outnumber the right vertices so reached by exactly one. This state is stable: a later augmentation from another free vertex keeps the reached left vertices matched, hence into the same set of right neighbours, which it therefore saturates again, so that reaches nothing new and stays failed. At the end the failed left vertices and the set of all left vertices reachable from them have , and any matching matches at most vertices of , so it has at most edges — which is the size of the matching returned, since every left vertex outside is matched.
Used by
none
From Mathlib
none
Discussion
Ask a question or add context. Endorsements and structured flags are kept in the review panel above.
0 comments