Paper
Finding Tree Decompositions of Small Treewidth
3 pages · 5 marked passages · pdflatex · download PDF · lax-689794
-
Graphs and Nice Tree Decompositions as Words
A tree decomposition of a graph is a tree whose nodes carry bags of vertices such that every vertex and every edge lies in a bag and the nodes whose bags contain a fixed vertex form a connected subtree; its width is the largest bag size minus one, and the treewidth of the graph is the least width of a decomposition (the archive's ). A tree decomposition is nice if its root and its leaves have empty bags and every other node is either an introduce node, whose bag is the bag of its single child plus one vertex, a forget node, whose bag is the bag of its single child minus one vertex, or a join node, with two children whose bags equal its own. This is the form dynamic programs over tree decompositions consume; it is due to Kloks.
1 import Mathlib.Combinatorics.SimpleGraph.Acyclic 2 import Mathlib.Combinatorics.SimpleGraph.Connectivity.Connected 3 import Lax228581.Treewidth 4 … module docstring, 42 lines 47 48 namespace Lax689794.GraphWords 49 50 open Lax228581.Treewidth 51 52 -- The word of a decomposition. 53 54 /-- The number of nodes of the decomposition word `D`: its first entry. -/ 55 def nodeCount (D : List ℕ) : ℕ := D.getD 0 0 56 57 /-- The kind of node `i`: `0` leaf, `1` introduce, `2` forget, `3` join. -/ 58 def kind (D : List ℕ) (i : ℕ) : ℕ := D.getD (1 + 3 * i) 0 59 60 /-- The vertex of node `i`, for an introduce or a forget node. -/ 61 def vertex (D : List ℕ) (i : ℕ) : ℕ := D.getD (2 + 3 * i) 0 62 63 /-- The second child of node `i`, for a join node. -/ 64 def other (D : List ℕ) (i : ℕ) : ℕ := D.getD (3 + 3 * i) 0 65 66 /-- The bag of node `i` among the vertices `0 … n - 1`, from the leaves up: the empty bag at a 67 leaf, the child's bag plus the vertex at an introduce node, minus it at a forget node, and the 68 child's bag at a join node. The first child of node `i + 1` is node `i`. -/ 69 def bagAt (n : ℕ) (D : List ℕ) : ℕ → Finset (Fin n) 70 | 0 => ∅ 71 | i + 1 => 72 if kind D (i + 1) = 1 then 73 if h : vertex D (i + 1) < n then insert ⟨vertex D (i + 1), h⟩ (bagAt n D i) 74 else bagAt n D i 75 else if kind D (i + 1) = 2 then 76 if h : vertex D (i + 1) < n then (bagAt n D i).erase ⟨vertex D (i + 1), h⟩ 77 else bagAt n D i 78 else if kind D (i + 1) = 3 then bagAt n D i 79 else ∅ 80 81 /-- Node `c` is a child of node `p`. -/ 82 def IsChild (D : List ℕ) (c p : ℕ) : Prop := 83 p < nodeCount D ∧ 84 ((kind D p = 1 ∨ kind D p = 2) ∧ c + 1 = p ∨ kind D p = 3 ∧ (c + 1 = p ∨ c = other D p)) 85 86 /-- The graph on the nodes `0 … N - 1` whose edges join a node to its children. -/ 87 def treeGraph (D : List ℕ) : SimpleGraph (Fin (nodeCount D)) where 88 Adj a b := a ≠ b ∧ (IsChild D a.val b.val ∨ IsChild D b.val a.val) 89 symm := ⟨fun _ _ h => ⟨h.1.symm, h.2.symm⟩⟩ 90 loopless := ⟨fun _ h => h.1 rfl⟩ 91 92 /-- **`D` is the word of a nice tree decomposition of `G` of width at most `w`.** -/ 93 structure NiceDecomposition {n : ℕ} (G : SimpleGraph (Fin n)) (w : ℕ) (D : List ℕ) : Prop where 94 /-- The word is `N` followed by three numbers for each of the `N` nodes. -/ 95 length_eq : D.length = 1 + 3 * nodeCount D 96 /-- There is a node. -/ 97 nonempty : 0 < nodeCount D 98 /-- Every node is a leaf, or an introduce node over the node before it whose vertex is not in 99 that node's bag, or a forget node over the node before it whose vertex is in that node's bag, 100 or a join node whose two children, the node before it and an earlier node, have its bag. -/ 101 shape : ∀ i, i < nodeCount D → 102 kind D i = 0 ∨ 103 (0 < i ∧ kind D i = 1 ∧ vertex D i < n ∧ 104 ∀ h : vertex D i < n, (⟨vertex D i, h⟩ : Fin n) ∉ bagAt n D (i - 1)) ∨ 105 (0 < i ∧ kind D i = 2 ∧ vertex D i < n ∧ 106 ∀ h : vertex D i < n, (⟨vertex D i, h⟩ : Fin n) ∈ bagAt n D (i - 1)) ∨ 107 (0 < i ∧ kind D i = 3 ∧ other D i + 1 < i ∧ 108 bagAt n D (other D i) = bagAt n D (i - 1)) 109 /-- Every node other than the last has exactly one parent. -/ 110 parent : ∀ c, c + 1 < nodeCount D → ∃! p, IsChild D c p 111 /-- The nodes form a tree. -/ 112 isTree : (treeGraph D).IsTree 113 /-- Every vertex is in a bag. -/ 114 covers : ∀ v : Fin n, ∃ i, i < nodeCount D ∧ v ∈ bagAt n D i 115 /-- Every two adjacent vertices are in a bag together. -/ 116 edges : ∀ u v : Fin n, G.Adj u v → 117 ∃ i, i < nodeCount D ∧ u ∈ bagAt n D i ∧ v ∈ bagAt n D i 118 /-- The nodes whose bags contain a fixed vertex form a connected subtree. -/ 119 connected : ∀ v : Fin n, 120 ((treeGraph D).induce {i : Fin (nodeCount D) | v ∈ bagAt n D i}).Connected 121 /-- Every bag has at most `w + 1` vertices. -/ 122 width : ∀ i, i < nodeCount D → (bagAt n D i).card ≤ w + 1 123 124 open Classical in 125 /-- **`g` is the word of the graph `G`**: the number of vertices, then the adjacency matrix row 126 by row. -/ 127 structure EncodesGraph {n : ℕ} (g : List ℕ) (G : SimpleGraph (Fin n)) : Prop where 128 /-- The word is the count followed by the matrix. -/ 129 length_eq : g.length = 1 + n * n 130 /-- The first entry is the number of vertices. -/ 131 head_eq : g.getD 0 0 = n 132 /-- The entry of the row `u` and column `v` is `1` when the two vertices are adjacent and `0` 133 otherwise. -/ 134 adj_eq : ∀ u v : Fin n, g.getD (1 + u.val * n + v.val) 0 = if G.Adj u v then 1 else 0 135 136 end Lax689794.GraphWords 137 -
Optimal Tree Decompositions from a Given One
The theorem of Bodlaender and Kloks. For all and there is a linear-time algorithm that, given a graph together with a tree decomposition of width at most , decides whether the treewidth of the graph is at most and, if so, finds a tree decomposition of width at most . The dependence on is .
H. L. Bodlaender and T. Kloks, "Efficient and constructive algorithms for the pathwidth and treewidth of graphs", Journal of Algorithms 21 (1996) 358–402. A simpler presentation, which this module follows, is E. Althaus and S. Ziegler, "Optimal tree decompositions revisited: a simpler linear-time FPT algorithm", arXiv:1912.09144 (2020), §3; the statement is Theorem 2.10 of H. L. Bodlaender, "A linear-time algorithm for finding tree-decompositions of small treewidth", SIAM Journal on Computing 25 (1996) 1305–1317, where it is used as a black box.
The formalized improvement result is derived from the exact graph algorithm. When , the program returns the supplied decomposition; otherwise it runs the graph algorithm with bound . Since in the latter case, its parameter-dependent bound is also bounded in terms of . The underlying characteristic dynamic program is used within the graph algorithm's vertex-by-vertex construction.
1 import Lax689794.GraphWords 2 import Lax808846.Ram 3 … module docstring, 48 lines 52 53 namespace Lax689794.BodlaenderKloks 54 55 open Lax808846.Ram Lax689794.GraphWords 56 57 open Classical in 58 /-- **The theorem of Bodlaender and Kloks, on a word RAM.** One program and one constant serve 59 every word length `W`, every graph `G`, every bound `k` and every nice tree decomposition `D` of 60 `G` of width at most `l`, provided the input `g ++ [k, l] ++ D` fits with room for 61 `c * 2 ^ (c * l ^ 3)` times a polynomial in its length. On such an input the program halts 62 within `c * 2 ^ (c * l ^ 3) * (|input| + 2) ^ c` instructions, writing `[0]` if the graph has no 63 tree decomposition of width at most `k`, and `1` followed by the word of a nice tree 64 decomposition of width at most `k` otherwise. -/ 65 axiom improveDecomposition : 66 ∃ (prog : Program) (c : ℕ), ∀ (W k l : ℕ) (n : ℕ) (G : SimpleGraph (Fin n)) (g D : List ℕ), 67 EncodesGraph g G → NiceDecomposition G l D → 68 (∀ v ∈ g ++ [k, l] ++ D, 69 c * 2 ^ (c * l ^ 3) * ((g ++ [k, l] ++ D).length + v + 1) ^ c ≤ 2 ^ W) → 70 ∃ (out : List ℕ) (t : ℕ), t ≤ c * 2 ^ (c * l ^ 3) * ((g ++ [k, l] ++ D).length + 2) ^ c ∧ 71 RunsTo W prog (g ++ [k, l] ++ D) out t ∧ 72 (out = [0] ∧ ¬ Lax228581.Treewidth.HasTreewidthAtMost G k ∨ 73 ∃ D', out = 1 :: D' ∧ NiceDecomposition G k D') 74 75 end Lax689794.BodlaenderKloks 76 -
no assumptions
The improvement step of Bodlaender–Kloks on a word RAM: given a nice decomposition of width it returns one of width at most or , proved by a dispatcher over the same exact algorithm (if the given decomposition is returned; otherwise the main algorithm runs on the graph and ).
-
Nice Tree Decompositions of Small Width Are Found in Fixed-Parameter Time
Bodlaender's theorem. For every constant one can decide in linear time whether a graph has treewidth at most , and if so construct a tree decomposition of width at most ; the dependence on is . Kloks' construction turns a tree decomposition into a nice one of the same width in time linear in its size, so the same holds for nice decompositions.
H. L. Bodlaender, "A linear-time algorithm for finding tree-decompositions of small treewidth", SIAM Journal on Computing 25 (1996) 1305–1317; T. Kloks, "Treewidth: Computations and Approximations", Lecture Notes in Computer Science 842, Springer 1994. A simplified presentation of the whole algorithm is E. Althaus and S. Ziegler, "Optimal tree decompositions revisited: a simpler linear-time FPT algorithm", arXiv:1912.09144 (2020).
The formalized algorithm inserts vertices one at a time, adding each new vertex to every bag of the preceding decomposition and applying the characteristic dynamic program to recover width at most . Compression controls the size of intermediate decompositions. This gives a polynomial dependence on the encoded graph length. The exported improvement theorem is derived from this graph algorithm.
1 import Lax689794.GraphWords 2 import Lax808846.Ram 3 … module docstring, 42 lines 46 47 namespace Lax689794.Bodlaender 48 49 open Lax808846.Ram Lax689794.GraphWords 50 51 open Classical in 52 /-- **Bodlaender's theorem with Kloks' niceness, on a word RAM.** One program and one constant 53 serve every word length `W`, every graph `G` on `n` vertices and every bound `k`, provided the 54 word — the graph followed by `k` — fits with room for `c * 2 ^ (c * k ^ 3)` times a polynomial 55 in its length. On such a word the program halts within `c * 2 ^ (c * k ^ 3) * (|g| + 2) ^ c` 56 instructions, writing `[0]` if the graph has no tree decomposition of width at most `k`, and `1` 57 followed by the word of a nice tree decomposition of width at most `k` otherwise. -/ 58 axiom niceDecomposition_computable : 59 ∃ (prog : Program) (c : ℕ), ∀ (W k n : ℕ) (G : SimpleGraph (Fin n)) (g : List ℕ), 60 EncodesGraph g G → 61 (∀ v ∈ g ++ [k], c * 2 ^ (c * k ^ 3) * ((g ++ [k]).length + v + 1) ^ c ≤ 2 ^ W) → 62 ∃ (out : List ℕ) (t : ℕ), t ≤ c * 2 ^ (c * k ^ 3) * (g.length + 2) ^ c ∧ 63 RunsTo W prog (g ++ [k]) out t ∧ 64 (out = [0] ∧ ¬ Lax228581.Treewidth.HasTreewidthAtMost G k ∨ 65 ∃ D, out = 1 :: D ∧ NiceDecomposition G k D) 66 67 end Lax689794.Bodlaender 68 -
no assumptions
Bodlaender's theorem with Kloks' niceness on a word RAM, proved by running the exact Bodlaender–Kloks algorithm (the vertex-by-vertex wrapper around the dynamic program over characteristics) as a functional program on a verified virtual machine and compiling it.
Loading the paper…