Double-tree approximation for metric TSP
StructureMetric cost function#✓fully proved
A cost function \(d\) assigning to each pair of vertices a value in a linearly ordered additive commutative monoid is metric when, for all vertices \(x\), \(y\), \(z\), it is symmetric, \(d(x, y) = d(y, x)\), zero on the diagonal, \(d(x, x) = 0\), nonnegative, \(0 \le d(x, y)\), and satisfies the triangle inequality \(d(x, z) \le d(x, y) + d(y, z)\).
structure IsMetricCost (d : α → α → R) : Prop where
symm : ∀ x y, d x y = d y x
self : ∀ x, d x x = 0
nonneg : ∀ x y, 0 ≤ d x y
triangle : ∀ x y z, d x z ≤ d x y + d y z
Used by 8
DefinitionCost of a walk#✓fully proved
Let \(d\) be a cost function on the vertices with values in an additive commutative monoid. For a vertex \(x\) and a list \(L = [y_1, \dots, y_n]\) of vertices, the cost of the walk from \(x\) through \(L\) is \(d(x, y_1) + d(y_1, y_2) + \dots + d(y_{n-1}, y_n)\), and \(0\) when \(L\) is empty.
def pathFrom (d : α → α → R) : α → List α → R
| _, [] => 0
| x, y :: L => d x y + pathFrom d y L
Used by 7
DefinitionCost of a closed tour#✓fully proved
For a cost function \(d\) on the vertices with values in an additive commutative monoid, the cost of the closed tour that visits \(x_0, x_1, \dots, x_k\) in order and returns to its first vertex is \(\sum_{i=1}^{k} d(x_{i-1}, x_i) + d(x_k, x_0)\). The empty tour costs \(0\).
InductiveRooted forest in left-child right-sibling form#✓fully proved
A rooted forest with vertices in \(\alpha\) is either empty, or consists of a first tree with root \(v\), whose subtrees form a forest (the children of \(v\)), followed by a forest of the remaining trees (the siblings of \(v\)).
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
Used by 22
APPROX-TSP-TOUR · APPROX-TSP-TOUR on a given minimum spanning tree costs at most twice any tour · Forest of a parent array below a vertex · Path as a forest · Minimum spanning tree of a vertex list · Rooted spanning tree of a vertex list · The forest of a parent tree spans all vertices · The closed preorder walk below a vertex costs at most twice the forest · Preorder of a forest · Preorder of a path · Preorder walk · Preorder walk with an accumulator · Result of the preorder walk with an accumulator · Forest of Prim's tree · APPROX-TSP-TOUR with Prim's tree is a 2-approximation · Edge sums over a parent tree · The preorder tour costs at most twice the tree · Weight of a forest below a vertex · Weight of the forest built from a parent array · A minimum spanning tree costs at most any tourDefinitionPreorder of a forest#✓fully proved
The list of the vertices of a forest in preorder: empty for the empty forest, and for a forest with first root \(v\), children forest \(C\) and sibling forest \(S\), the vertex \(v\), followed by the preorder of \(C\), followed by the preorder of \(S\).
The preorder walk computes this list without appending lists.
def preorder : Forest α → List α
| nil => []
| cons v ch sib => v :: ch.preorder ++ sib.preorder
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
Uses 1 · Used by 13
APPROX-TSP-TOUR · APPROX-TSP-TOUR on a given minimum spanning tree costs at most twice any tour · Rooted spanning tree of a vertex list · The forest of a parent tree spans all vertices · The closed preorder walk below a vertex costs at most twice the forest · Preorder of a path · Result of the preorder walk with an accumulator · APPROX-TSP-TOUR with Prim's tree is a 2-approximation · Edge sums over a parent tree · The preorder tour costs at most twice the tree · Weight of the forest built from a parent array · A minimum spanning tree costs at most any tourDefinitionWeight of a forest below a vertex#✓fully proved
For a cost function \(d\) and a vertex \(p\), the weight of a forest hanging below \(p\) is the total cost of its tree edges: each top-level vertex \(v\) is joined to \(p\) by an edge of cost \(d(p, v)\), and each vertex \(u\) is joined to each of its children \(c\) by an edge of cost \(d(u, c)\). The empty forest has weight \(0\).
def weight (d : α → α → R) (p : α) : Forest α → R
| nil => 0
| cons v ch sib => d p v + ch.weight d v + sib.weight d p
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
Uses 1 · Used by 7
DefinitionPath as a forest#✓fully proved
The forest of a list \(x_1, x_2, \dots, x_n\) of vertices is the path \(x_1, x_2, \dots, x_n\): \(x_1\) is its only top-level vertex and each \(x_{i+1}\) is the only child of \(x_i\). The empty list gives the empty forest.
def chain : List α → Forest α
| [] => nil
| x :: xs => cons x (chain xs) nil
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
Uses 1 · Used by 2
DefinitionPreorder walk with an accumulator#✓fully proved
For a forest \(F\) and a list \(a\) of vertices, this is the timed computation defined as follows. On the empty forest it returns \(a\) at no cost. On a forest with first root \(v\), children forest \(C\) and sibling forest \(S\), it charges one time unit, walks \(S\) with accumulator \(a\) to get a list \(b\), walks \(C\) with accumulator \(b\) to get a list \(c\), and returns \(v\) followed by \(c\). It thus returns the vertices of \(F\) in preorder followed by \(a\), at one time unit per vertex of \(F\).
The accumulator means no list is ever appended, so the untimed work is linear as well.
def preorderWalkAux : Forest α → List α → TimeM ℕ (List α)
| .nil, acc => pure acc
| .cons v ch sib, acc => do
✓
let b ← preorderWalkAux sib acc
let a ← preorderWalkAux ch b
pure (v :: a)
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
Uses 1 · Used by 6
DefinitionPreorder walk#✓fully proved
For a forest \(F\), the preorder walk of \(F\) is the preorder walk of \(F\) with the empty list as accumulator: a timed computation that returns the vertices of \(F\) in preorder, at one time unit per vertex.
def preorderWalk (F : Forest α) : TimeM ℕ (List α) := preorderWalkAux F []
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
def preorderWalkAux : Forest α → List α → TimeM ℕ (List α)
| .nil, acc => pure acc
| .cons v ch sib, acc => do
✓
let b ← preorderWalkAux sib acc
let a ← preorderWalkAux ch b
pure (v :: a)
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:104
Uses 2 · Used by 5
DefinitionThe APPROX-TSP-TOUR algorithm#✓fully proved
CLRS APPROX-TSP-TOUR, steps 3 and 4: given a root \(r\)
and a forest \(F\) (the subtrees of a spanning tree with root \(r\)), return the tour that lists \(r\)
followed by the vertices of \(F\) in preorder. As a timed computation it charges one unit for \(r\)
and one unit for each vertex visited by the preorder walk of \(F\).
def approxTSPTour (r : α) (F : Forest α) : TimeM ℕ (List α) := do
✓
let w ← preorderWalk F
pure (r :: w)
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
def preorderWalk (F : Forest α) : TimeM ℕ (List α) := preorderWalkAux F []
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:113
Uses 2 · Used by 5
TheoremResult of the preorder walk with an accumulator#✓fully proved
For every forest \(F\) and every list \(a\) of vertices, the preorder walk of \(F\) with accumulator \(a\) returns the vertices of \(F\) in preorder followed by \(a\).
theorem preorderWalkAux_ret (F : Forest α) (acc : List α) :
(preorderWalkAux F acc).ret = F.preorder ++ acc
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
def preorderWalkAux : Forest α → List α → TimeM ℕ (List α)
| .nil, acc => pure acc
| .cons v ch sib, acc => do
✓
let b ← preorderWalkAux sib acc
let a ← preorderWalkAux ch b
pure (v :: a)
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:104
Uses 3 · Used by 3
TheoremRunning time of APPROX-TSP-TOUR#✓fully proved
For every root \(r\) and forest \(F\), the running time of
APPROX-TSP-TOUR on \(r\) and \(F\) equals the length of the list of \(r\) followed by the vertices of
\(F\) in preorder: one unit per vertex of the returned tour.
@[simp]
theorem approxTSPTour_time (r : α) (F : Forest α) :
(approxTSPTour r F).time = (r :: F.preorder).length
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
def approxTSPTour (r : α) (F : Forest α) : TimeM ℕ (List α) := do
✓
let w ← preorderWalk F
pure (r :: w)
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:117
Uses 5
TheoremChanging the starting vertex of a walk#✓fully proved
Let \(d\) be a cost function on the vertices with values in a linearly ordered additive commutative monoid, which is symmetric, zero on the diagonal, nonnegative, and satisfies the triangle inequality. For vertices \(q\), \(p\) and a list \(L\) of vertices, the cost of the walk from \(q\) through \(L\) is at most \(d(q, p)\) plus the cost of the walk from \(p\) through \(L\).
theorem pathFrom_le_add (hd : IsMetricCost d) (q p : α) (L : List α) :
pathFrom d q L ≤ d q p + pathFrom d p L
structure IsMetricCost (d : α → α → R) : Prop where
symm : ∀ x y, d x y = d y x
self : ∀ x, d x x = 0
nonneg : ∀ x y, 0 ≤ d x y
triangle : ∀ x y z, d x z ≤ d x y + d y z
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:60
def pathFrom (d : α → α → R) : α → List α → R
| _, [] => 0
| x, y :: L => d x y + pathFrom d y L
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:67
Uses 2 · Used by 1
TheoremShortcutting a closed walk through its base point#✓fully proved
Let \(d\) be a cost function on the vertices with values in a linearly ordered additive commutative monoid, which is symmetric, zero on the diagonal, nonnegative, and satisfies the triangle inequality. For a vertex \(p\) and lists \(A\), \(B\) of vertices, the cost of the walk that starts at \(p\), visits \(A\) and then \(B\) in order and returns to \(p\) is at most the cost of the walk from \(p\) through \(A\) back to \(p\) plus the cost of the walk from \(p\) through \(B\) back to \(p\).
theorem pathFrom_append_append_le (hd : IsMetricCost d) (p : α) (A B : List α) :
pathFrom d p (A ++ B ++ [p]) ≤ pathFrom d p (A ++ [p]) + pathFrom d p (B ++ [p])
structure IsMetricCost (d : α → α → R) : Prop where
symm : ∀ x y, d x y = d y x
self : ∀ x, d x x = 0
nonneg : ∀ x y, 0 ≤ d x y
triangle : ∀ x y z, d x z ≤ d x y + d y z
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:60
def pathFrom (d : α → α → R) : α → List α → R
| _, [] => 0
| x, y :: L => d x y + pathFrom d y L
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:67
Uses 3 · Used by 1
TheoremRerouting the end of a walk#✓fully proved
Let \(d\) be a cost function on the vertices with values in a linearly ordered additive commutative monoid, which is symmetric, zero on the diagonal, nonnegative, and satisfies the triangle inequality. For vertices \(v\), \(p\) and a list \(C\) of vertices, the cost of the walk from \(v\) through \(C\) ending at \(p\) is at most the cost of the walk from \(v\) through \(C\) ending back at \(v\), plus \(d(v, p)\).
theorem pathFrom_append_singleton_le (hd : IsMetricCost d) (v p : α) (C : List α) :
pathFrom d v (C ++ [p]) ≤ pathFrom d v (C ++ [v]) + d v p
structure IsMetricCost (d : α → α → R) : Prop where
symm : ∀ x y, d x y = d y x
self : ∀ x, d x x = 0
nonneg : ∀ x y, 0 ≤ d x y
triangle : ∀ x y z, d x z ≤ d x y + d y z
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:60
def pathFrom (d : α → α → R) : α → List α → R
| _, [] => 0
| x, y :: L => d x y + pathFrom d y L
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:67
Uses 2 · Used by 1
TheoremThe closed preorder walk below a vertex costs at most twice the forest#✓fully proved
Let \(d\) be a cost function on the vertices with values in a linearly ordered additive commutative monoid, which is symmetric, zero on the diagonal, nonnegative, and satisfies the triangle inequality. For a forest \(F\) and a vertex \(p\), let \(w\) be the weight of \(F\) hanging below \(p\): the total cost of the edges joining \(p\) to the top-level vertices of \(F\) and each vertex of \(F\) to its children. Then the cost of the walk that starts at \(p\), visits the vertices of \(F\) in preorder and returns to \(p\) is at most \(w + w\).
theorem pathFrom_preorder_le (hd : IsMetricCost d) (F : Forest α) (p : α) :
pathFrom d p (F.preorder ++ [p]) ≤ F.weight d p + F.weight d p
structure IsMetricCost (d : α → α → R) : Prop where
symm : ∀ x y, d x y = d y x
self : ∀ x, d x x = 0
nonneg : ∀ x y, 0 ≤ d x y
triangle : ∀ x y z, d x z ≤ d x y + d y z
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:60
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
def pathFrom (d : α → α → R) : α → List α → R
| _, [] => 0
| x, y :: L => d x y + pathFrom d y L
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:67
Uses 7 · Used by 1
TheoremThe preorder tour costs at most twice the tree#✓fully proved
Let \(d\) be a cost function on the vertices with values in a linearly ordered additive commutative monoid that is symmetric, zero on the diagonal, nonnegative and satisfies the triangle inequality. Let \(T\) be a rooted tree with root \(r\), given by the forest \(F\) of the subtrees of \(r\), and let \(w(T)\) be its weight, the total cost of its edges. Then the closed tour that visits \(r\), then the vertices of \(F\) in preorder, and returns to \(r\) costs at most \(2\,w(T)\).
theorem tourCost_preorder_le (hd : IsMetricCost d) (r : α) (F : Forest α) :
tourCost d (r :: F.preorder) ≤ 2 • F.weight d r
structure IsMetricCost (d : α → α → R) : Prop where
symm : ∀ x y, d x y = d y x
self : ∀ x, d x x = 0
nonneg : ∀ x y, 0 ≤ d x y
triangle : ∀ x y z, d x z ≤ d x y + d y z
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:60
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
def tourCost (d : α → α → R) : List α → R
| [] => 0
| h :: t => pathFrom d h (t ++ [h])
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:72
Sources
- CLRS Theorem 35.2, first half.
Uses 6 · Used by 2
TheoremPreorder of a path#✓fully proved
For every list \(L\) of vertices, the preorder of the forest of \(L\) (the path through the vertices of \(L\) in order) is \(L\) itself.
@[simp]
theorem Forest.preorder_chain (xs : List α) : (Forest.chain xs).preorder = xs
def chain : List α → Forest α
| [] => nil
| x :: xs => cons x (chain xs) nil
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:96
Uses 3 · Used by 1
DefinitionRooted spanning tree of a vertex list#✓fully proved
The tree with root \(r\) and subtree forest \(F\) is a spanning tree of a list \(V\) of vertices when the vertices of \(V\) are distinct and the list of \(r\) followed by the vertices of \(F\) in preorder is a permutation of \(V\): the vertices of the tree are those of \(V\), each exactly once.
def IsSpanning (V : List α) (r : α) (F : Forest α) : Prop := V.Nodup ∧ (r :: F.preorder).Perm V
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
Uses 2 · Used by 5
DefinitionMinimum spanning tree of a vertex list#✓fully proved
Let \(d\) be a cost function on the vertices with values in a linearly ordered additive commutative monoid. The tree with root \(r\) and subtree forest \(F\) is a minimum spanning tree of a list \(V\) of vertices for \(d\) when it is a spanning tree of \(V\) (the vertices of \(V\) are distinct and the list of \(r\) followed by the vertices of \(F\) in preorder is a permutation of \(V\)) and, for every vertex \(r'\) and forest \(F'\) such that the tree with root \(r'\) and subtree forest \(F'\) is a spanning tree of \(V\), the weight of \(F\) below \(r\) is at most the weight of \(F'\) below \(r'\).
def IsMinSpanning (d : α → α → R) (V : List α) (r : α) (F : Forest α) : Prop :=
IsSpanning V r F ∧ ∀ r' F', IsSpanning V r' F' → F.weight d r ≤ F'.weight d r'
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
def IsSpanning (V : List α) (r : α) (F : Forest α) : Prop := V.Nodup ∧ (r :: F.preorder).Perm V
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:246
DefinitionTour of a vertex list#✓fully proved
A list \(H\) is a tour of a list \(V\) of vertices when the vertices of \(V\) are distinct and \(H\) is a permutation of \(V\): \(H\) lists each vertex of \(V\) exactly once and nothing else.
def IsTour (V H : List α) : Prop := V.Nodup ∧ H.Perm V
TheoremA minimum spanning tree costs at most any tour#✓fully proved
Let \(d\) be a cost function on the vertices with values in a linearly ordered additive commutative monoid that is symmetric, zero on the diagonal, nonnegative and satisfies the triangle inequality. Let \(V\) be a list of distinct vertices. Let \(T\) be a minimum spanning tree of \(V\) for \(d\): a rooted tree whose vertices are the elements of \(V\), each once, whose weight (the total cost of its edges) is at most that of every such tree. Let \(H\) be a tour of \(V\), a list that is a permutation of \(V\). Then the weight of \(T\) is at most the cost of the closed tour \(H\).
A tour minus its closing edge is a spanning path, which is a spanning tree.
theorem weight_le_tourCost (hd : IsMetricCost d) {V : List α} {r : α} {F : Forest α}
(hT : IsMinSpanning d V r F) {H : List α} (hH : IsTour V H) :
F.weight d r ≤ tourCost d H
structure IsMetricCost (d : α → α → R) : Prop where
symm : ∀ x y, d x y = d y x
self : ∀ x, d x x = 0
nonneg : ∀ x y, 0 ≤ d x y
triangle : ∀ x y z, d x z ≤ d x y + d y z
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:60
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
def IsMinSpanning (d : α → α → R) (V : List α) (r : α) (F : Forest α) : Prop :=
IsSpanning V r F ∧ ∀ r' F', IsSpanning V r' F' → F.weight d r ≤ F'.weight d r'
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:249
def IsTour (V H : List α) : Prop := V.Nodup ∧ H.Perm V
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:253
def tourCost (d : α → α → R) : List α → R
| [] => 0
| h :: t => pathFrom d h (t ++ [h])
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:72
Sources
- CLRS Theorem 35.2, second half.
Uses 11 · Used by 1
TheoremThe approximate TSP tour is a tour#✓fully proved
Let \(V\) be a list of distinct vertices, and let \(r\)
and \(F\) be such that \(r\) followed by the vertices of the forest \(F\) in preorder is a permutation
of \(V\) (the tree with root \(r\) and subtree forest \(F\) spans \(V\)). Then the list returned by
APPROX-TSP-TOUR on \(r\) and \(F\) is a tour of \(V\): it is a permutation of \(V\).
theorem approxTSPTour_isTour {V : List α} {r : α} {F : Forest α} (hT : IsSpanning V r F) :
IsTour V (approxTSPTour r F).ret
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
def IsSpanning (V : List α) (r : α) (F : Forest α) : Prop := V.Nodup ∧ (r :: F.preorder).Perm V
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:246
def IsTour (V H : List α) : Prop := V.Nodup ∧ H.Perm V
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:253
def approxTSPTour (r : α) (F : Forest α) : TimeM ℕ (List α) := do
✓
let w ← preorderWalk F
pure (r :: w)
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:117
Uses 8 · Used by 1
TheoremAPPROX-TSP-TOUR on a given minimum spanning tree costs at most twice any tour#✓fully proved
Let \(d\) be a
cost function on vertices with values in a linearly ordered additive commutative monoid that is
symmetric, zero on the diagonal, nonnegative and satisfies the triangle inequality. Let \(V\) be a
list of vertices, let the tree with root \(r\) and subtree forest \(F\) be a minimum spanning tree of
\(V\) for \(d\), and let \(H\) be a tour of \(V\). Then the cost under \(d\) of the closed tour returned by
APPROX-TSP-TOUR on \(r\) and \(F\) is at most twice the cost under \(d\) of the closed tour \(H\).
theorem approxTSPTour_two_approx (hd : IsMetricCost d) {V : List α} {r : α} {F : Forest α}
(hT : IsMinSpanning d V r F) {H : List α} (hH : IsTour V H) :
tourCost d (approxTSPTour r F).ret ≤ 2 • tourCost d H
structure IsMetricCost (d : α → α → R) : Prop where
symm : ∀ x y, d x y = d y x
self : ∀ x, d x x = 0
nonneg : ∀ x y, 0 ≤ d x y
triangle : ∀ x y z, d x z ≤ d x y + d y z
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:60
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
def IsMinSpanning (d : α → α → R) (V : List α) (r : α) (F : Forest α) : Prop :=
IsSpanning V r F ∧ ∀ r' F', IsSpanning V r' F' → F.weight d r ≤ F'.weight d r'
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:249
def IsTour (V H : List α) : Prop := V.Nodup ∧ H.Perm V
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:253
def tourCost (d : α → α → R) : List α → R
| [] => 0
| h :: t => pathFrom d h (t ++ [h])
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:72
def approxTSPTour (r : α) (F : Forest α) : TimeM ℕ (List α) := do
✓
let w ← preorderWalk F
pure (r :: w)
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:117
Sources
- CLRS, third edition, Theorem 35.2.
DefinitionOne step up a parent array#✓fully proved
Let \(p\) be a parent array on the vertices \(\{0, \dots, n-1\}\), assigning to each vertex \(v\) either a parent \(p(v)\) or no parent. Then \(\operatorname{up}(v)\) is the parent \(p(v)\) when \(v\) has one, and \(v\) itself otherwise, so a root stays put.
Used by 8
DefinitionChildren in a parent array#✓fully proved
Let \(p\) assign to each vertex of \(\{0, \dots, n-1\}\) either a parent or nothing. The children of a vertex \(v\) are the vertices \(c\) whose parent \(p(c)\) is \(v\), listed in increasing order.
def children (v : Fin n) : List (Fin n) := (List.finRange n).filter fun c => par c = some v
DefinitionForest of a parent array below a vertex#✓fully proved
Let \(p\) assign to each vertex of \(\{0, \dots, n-1\}\) either a parent or nothing. For \(k \in \mathbb{N}\) and a vertex \(v\), the forest below \(v\) of depth \(k\) is empty when \(k = 0\). For depth \(k + 1\) it has one tree for each child \(c\) of \(v\) (each vertex whose parent is \(v\)), in increasing order of \(c\), namely \(c\) with the forest below \(c\) of depth \(k\) as its subtrees.
def buildForest : ℕ → Fin n → Forest (Fin n)
| 0, _ => .nil
| k + 1, v => (children par v).foldr (fun c acc => .cons c (buildForest k c) acc) .nil
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
def children (v : Fin n) : List (Fin n) := (List.finRange n).filter fun c => par c = some v
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:69
Uses 2 · Used by 5
StructureParent tree#✓fully proved
Let \(p\) assign to each vertex of \(\{0, \dots, n-1\}\) either a parent or nothing, and let a step up move a vertex to its parent, leaving a vertex without parent in place. The parent array \(p\) is a parent tree with root \(r\) when \(r\) has no parent and every vertex reaches \(r\) after finitely many steps up.
DefinitionDescendant within \(k\) levels#✓fully proved
Let \(p\) assign to each vertex of \(\{0, \dots, n-1\}\) either a parent or nothing, and let a step up move a vertex to its parent, leaving a vertex without parent in place. For \(k \in \mathbb{N}\), a vertex \(u\) lies strictly below a vertex \(v\), at most \(k\) levels down, when for some \(j < k\) the vertex reached from \(u\) after \(j\) steps up has parent \(v\).
def DescK (k : ℕ) (v u : Fin n) : Prop := ∃ j < k, par ((up par)^[j] u) = some v
def up (v : Fin n) : Fin n := (par v).getD v
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:66
Uses 1 · Used by 3
TheoremWeight of the forest built from a parent array#✓fully proved
Let \(p\) be a parent array on the vertices \(\{0, \dots, n-1\}\), let \(d\) be a cost on ordered pairs of vertices with values in an additive commutative monoid, and let \(\operatorname{up}(u)\) be the parent of \(u\), or \(u\) itself if \(u\) has no parent. For every \(k \in \mathbb{N}\) and every vertex \(v\), let \(F\) be the forest of the subtrees of the children of \(v\) in \(p\), cut off \(k\) levels below \(v\). Then the weight under \(d\) of \(F\) hanging below \(v\) equals the sum of \(d(\operatorname{up}(u), u)\) over the vertices \(u\) of \(F\) in preorder.
theorem weight_buildForest : ∀ (k : ℕ) (v : Fin n),
(buildForest par k v).weight d v =
((buildForest par k v).preorder.map fun u => d (up par u) u).sum
def buildForest : ℕ → Fin n → Forest (Fin n)
| 0, _ => .nil
| k + 1, v => (children par v).foldr (fun c acc => .cons c (buildForest k c) acc) .nil
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:72
def up (v : Fin n) : Fin n := (par v).getD v
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:66
Uses 6 · Used by 1
TheoremEvery non-root vertex lies below the root#✓fully proved
Let \(p\) assign to each vertex of \(\{0, \dots, n-1\}\) either a parent or nothing, forming a parent tree with root \(r\), and let a step up move a vertex to its parent, leaving a vertex without parent in place. Then every vertex \(u \ne r\) lies strictly below \(r\), at most \(n\) levels down: for some \(j < n\), the vertex reached from \(u\) after \(j\) steps up has parent \(r\).
theorem descK_root (ht : ParentTree par root) {u : Fin n} (hu : u ≠ root) :
DescK par n root u
structure ParentTree (root : Fin n) : Prop where
root_none : par root = none
reach : ∀ v, ∃ j, (up par)^[j] v = root
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:77
def DescK (k : ℕ) (v u : Fin n) : Prop := ∃ j < k, par ((up par)^[j] u) = some v
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:82
Uses 3 · Used by 2
TheoremThe forest of a parent tree spans all vertices#✓fully proved
Let \(p\) assign to each vertex of \(\{0, \dots, n-1\}\) either a parent or nothing, forming a parent tree with root \(r\). Then \(r\) together with the forest below \(r\) of depth \(n\) built from \(p\) is a spanning tree of \(\{0, \dots, n-1\}\): \(r\) followed by the vertices of the forest in preorder lists every vertex exactly once.
theorem isSpanning_buildForest (ht : ParentTree par root) :
IsSpanning (List.finRange n) root (buildForest par n root)
structure ParentTree (root : Fin n) : Prop where
root_none : par root = none
reach : ∀ v, ∃ j, (up par)^[j] v = root
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:77
def IsSpanning (V : List α) (r : α) (F : Forest α) : Prop := V.Nodup ∧ (r :: F.preorder).Perm V
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:246
def buildForest : ℕ → Fin n → Forest (Fin n)
| 0, _ => .nil
| k + 1, v => (children par v).foldr (fun c acc => .cons c (buildForest k c) acc) .nil
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:72
Uses 9 · Used by 1
DefinitionComplete graph as an ordered adjacency#✓fully proved
For \(n \in \mathbb{N}\), the complete graph on the vertices \(\{0, \dots, n-1\}\) as a directed adjacency: the vertices are listed in increasing order, and the neighbours of each vertex \(u\) are all vertices other than \(u\), in increasing order.
def completeAdjacency (n : ℕ) : DirectedAdjacency (Fin n) where
vertices := List.finRange n
vertices_nodup := List.nodup_finRange n
vertices_complete := List.mem_finRange
adjacency u := (List.finRange n).filter (· ≠ u)
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:40
Uses 1 · Used by 5
DefinitionSymmetrized edge weights#✓fully proved
Given costs \(d(u,v)\) on the vertices \(\{0, \dots, n-1\}\) with values in a type with commutative addition, the weight of an unordered pair \(\{u, v\}\) is \(d(u,v) + d(v,u)\), which does not depend on the order of \(u\) and \(v\). When \(d\) is symmetric this is twice the cost, which leaves minimum spanning trees unchanged.
def symWeight {W : Type*} [Add W] [Std.Commutative (α := W) (· + ·)] (d : Fin n → Fin n → W) :
Sym2 (Fin n) → W :=
Sym2.lift ⟨fun u v => d u v + d v u, fun _ _ => Std.Commutative.comm _ _⟩
DefinitionPrim's parent array on the complete graph#✓fully proved
Given costs \(d(u,v)\) on the vertices \(\{0, \dots, n-1\}\) with values in a linearly ordered type with a zero and commutative addition, and a root \(r\), this is the parent array returned by Prim's algorithm run from \(r\) on the complete graph on these vertices, with the weight of the edge \(\{u, v\}\) equal to \(d(u,v) + d(v,u)\): it sends each vertex to its parent, or to no parent.
def primParents {W : Type*} [LinearOrder W] [Zero W] [Add W] [Std.Commutative (α := W) (· + ·)]
(d : Fin n → Fin n → W) (root : Fin n) : Fin n → Option (Fin n) :=
let parents := (Prim.prim (completeAdjacency n) (symWeight d) root).ret
fun v => parents[v]
public def prim {W : Type u} [LinearOrder W] [Zero W] {n : Nat}
(graph : DirectedAdjacency (Fin n)) (weight : Sym2 (Fin n) → W) (root : Fin n) :
TimeM ((Fin 5 → Nat) × Nat × Nat) (Vector (Option (Fin n)) n) :=
let actual := Cslib.Algorithms.Lean.Prim.worker graph weight root
⟨actual.ret.parent, actual.time⟩
CSLibExt/Algorithms/Lean/Graph/Prim/Basic.lean:113
def completeAdjacency (n : ℕ) : DirectedAdjacency (Fin n) where
vertices := List.finRange n
vertices_nodup := List.nodup_finRange n
vertices_complete := List.mem_finRange
adjacency u := (List.finRange n).filter (· ≠ u)
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:312
def symWeight {W : Type*} [Add W] [Std.Commutative (α := W) (· + ·)] (d : Fin n → Fin n → W) :
Sym2 (Fin n) → W :=
Sym2.lift ⟨fun u v => d u v + d v u, fun _ _ => Std.Commutative.comm _ _⟩
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:320
Uses 3 · Used by 6
DefinitionForest of Prim's tree#✓fully proved
Given costs \(d(u,v)\) on the vertices \(\{0, \dots, n-1\}\) with values in a linearly ordered type with a zero and commutative addition, and a root \(r\), take Prim's parent array for \(d\) and \(r\) (Prim's algorithm run from \(r\) on the complete graph with edge weights \(d(u,v) + d(v,u)\)). This forest is the forest of the subtrees below \(r\) in that parent array, cut off \(n\) levels below \(r\), in left-child right-sibling form, with the children of each vertex in vertex order.
def primForest {W : Type*} [LinearOrder W] [Zero W] [Add W] [Std.Commutative (α := W) (· + ·)]
(d : Fin n → Fin n → W) (root : Fin n) : Forest (Fin n) :=
buildForest (primParents d root) n root
inductive Forest (α : Type u) where
| nil : Forest α
| cons (v : α) (children siblings : Forest α) : Forest α
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:77
def buildForest : ℕ → Fin n → Forest (Fin n)
| 0, _ => .nil
| k + 1, v => (children par v).foldr (fun c acc => .cons c (buildForest k c) acc) .nil
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:72
def primParents {W : Type*} [LinearOrder W] [Zero W] [Add W] [Std.Commutative (α := W) (· + ·)]
(d : Fin n → Fin n → W) (root : Fin n) : Fin n → Option (Fin n) :=
let parents := (Prim.prim (completeAdjacency n) (symWeight d) root).ret
fun v => parents[v]
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:325
Uses 3 · Used by 4
DefinitionAPPROX-TSP-TOUR with Prim's tree#✓fully proved
Given costs \(d(u,v)\) on the vertices \(\{0, \dots, n-1\}\) with values in a linearly ordered type with a zero and commutative addition, and a root \(r\), the tour is \(r\) followed by the vertices of the forest of Prim's tree below \(r\) in preorder. Its running time counts one unit per vertex of the tour; running Prim's algorithm and building the forest are not counted.
This is CLRS APPROX-TSP-TOUR, with the minimum spanning tree computed by Prim.
def primTSPTour {W : Type*} [LinearOrder W] [Zero W] [Add W] [Std.Commutative (α := W) (· + ·)]
(d : Fin n → Fin n → W) (root : Fin n) : TimeM ℕ (List (Fin n)) :=
approxTSPTour root (primForest d root)
def approxTSPTour (r : α) (F : Forest α) : TimeM ℕ (List α) := do
✓
let w ← preorderWalk F
pure (r :: w)
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:117
def primForest {W : Type*} [LinearOrder W] [Zero W] [Add W] [Std.Commutative (α := W) (· + ·)]
(d : Fin n → Fin n → W) (root : Fin n) : Forest (Fin n) :=
buildForest (primParents d root) n root
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:331
Uses 2 · Used by 2
TheoremNeighbours in the complete adjacency#✓fully proved
For all vertices \(u, v\) of \(\{0, \dots, n-1\}\), \(v\) is listed among the neighbours of \(u\) in the complete graph as an ordered adjacency if and only if \(u\) and \(v\) are adjacent in the complete simple graph on \(\{0, \dots, n-1\}\), that is, \(u \ne v\).
theorem mem_completeAdjacency (u v : Fin n) :
v ∈ (completeAdjacency n).adjacency u ↔ (⊤ : SimpleGraph (Fin n)).Adj u v
def completeAdjacency (n : ℕ) : DirectedAdjacency (Fin n) where
vertices := List.finRange n
vertices_nodup := List.nodup_finRange n
vertices_complete := List.mem_finRange
adjacency u := (List.finRange n).filter (· ≠ u)
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:312
Uses 2 · Used by 2
AbbreviationPrim's tree#✓fully proved
Given costs \(d(u,v)\) on the vertices \(\{0, \dots, n-1\}\) with values in a linearly ordered type with a zero and commutative addition, and a root \(r\), Prim's tree is the simple graph on these vertices in which distinct vertices \(u\) and \(v\) are adjacent when one of them is the parent of the other in Prim's parent array for \(d\) and \(r\).
abbrev primTree {W : Type*} [LinearOrder W] [Zero W] [Add W] [Std.Commutative (α := W) (· + ·)]
(d : Fin n → Fin n → W) (root : Fin n) : SimpleGraph (Fin n) :=
SimpleGraph.fromRel fun u v => primParents d root v = some u
def primParents {W : Type*} [LinearOrder W] [Zero W] [Add W] [Std.Commutative (α := W) (· + ·)]
(d : Fin n → Fin n → W) (root : Fin n) : Fin n → Option (Fin n) :=
let parents := (Prim.prim (completeAdjacency n) (symWeight d) root).ret
fun v => parents[v]
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:325
Uses 1 · Used by 4
TheoremPrim's tree is a spanning tree#✓fully proved
For costs \(d(u,v)\) on the vertices \(\{0, \dots, n-1\}\) with values in any linearly ordered type with a zero and commutative addition, and any root \(r\), Prim's tree for \(d\) and \(r\) is a tree on all of \(\{0, \dots, n-1\}\), that is, a spanning tree of the complete graph.
theorem primTree_isTree {W : Type*} [LinearOrder W] [Zero W] [Add W]
[Std.Commutative (α := W) (· + ·)] (d : Fin n → Fin n → W) (root : Fin n) :
(primTree d root).IsTree
abbrev primTree {W : Type*} [LinearOrder W] [Zero W] [Add W] [Std.Commutative (α := W) (· + ·)]
(d : Fin n → Fin n → W) (root : Fin n) : SimpleGraph (Fin n) :=
SimpleGraph.fromRel fun u v => primParents d root v = some u
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:348
Uses 5 · Used by 1
TheoremPrim's tree is a minimum spanning tree#✓fully proved
Let \(d(u,v)\) be real costs on the vertices \(\{0, \dots, n-1\}\), let \(r\) be a vertex, and weigh each edge \(\{u, v\}\) by \(d(u,v) + d(v,u)\). Then Prim's tree for \(d\) and \(r\) is a tree, and for every tree \(H\) on these vertices the total weight of the edges of Prim's tree is at most the total weight of the edges of \(H\).
theorem primTree_isMinimumSpanningTree (d : Fin n → Fin n → ℝ) (root : Fin n) :
(primTree d root).IsTree ∧ ∀ H : SimpleGraph (Fin n), H.IsTree →
(∑ e ∈ (primTree d root).edgeFinset, symWeight d e) ≤
∑ e ∈ H.edgeFinset, symWeight d e
abbrev primTree {W : Type*} [LinearOrder W] [Zero W] [Add W] [Std.Commutative (α := W) (· + ·)]
(d : Fin n → Fin n → W) (root : Fin n) : SimpleGraph (Fin n) :=
SimpleGraph.fromRel fun u v => primParents d root v = some u
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:348
def symWeight {W : Type*} [Add W] [Std.Commutative (α := W) (· + ·)] (d : Fin n → Fin n → W) :
Sym2 (Fin n) → W :=
Sym2.lift ⟨fun u v => d u v + d v u, fun _ _ => Std.Commutative.comm _ _⟩
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:320
Uses 7 · Used by 1
TheoremPrim's parent array is a parent tree#✓fully proved
Let \(W\) be a linearly ordered type with a zero and a commutative addition, let \(d\) assign a weight in \(W\) to each ordered pair of vertices of \(\{0, \dots, n-1\}\), and let \(r\) be a vertex. Then Prim's parent array for \(d\) from \(r\) is a parent tree with root \(r\): \(r\) has no parent, and every vertex reaches \(r\) after finitely many steps up, where a step up moves a vertex to its parent and leaves a vertex without parent in place.
theorem parentTree_primParents {W : Type*} [LinearOrder W] [Zero W] [Add W]
[Std.Commutative (α := W) (· + ·)] (d : Fin n → Fin n → W) (root : Fin n) :
ParentTree (primParents d root) root
structure ParentTree (root : Fin n) : Prop where
root_none : par root = none
reach : ∀ v, ∃ j, (up par)^[j] v = root
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:77
def primParents {W : Type*} [LinearOrder W] [Zero W] [Add W] [Std.Commutative (α := W) (· + ·)]
(d : Fin n → Fin n → W) (root : Fin n) : Fin n → Option (Fin n) :=
let parents := (Prim.prim (completeAdjacency n) (symWeight d) root).ret
fun v => parents[v]
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:325
Uses 9 · Used by 2
TheoremPrim's forest spans all vertices#✓fully proved
Let \(W\) be a linearly ordered type with a zero and a commutative addition, let \(d\) assign a weight in \(W\) to each ordered pair of vertices of \(\{0, \dots, n-1\}\), and let \(r\) be a vertex. Then \(r\) together with Prim's forest for \(d\) and \(r\) is a spanning tree of \(\{0, \dots, n-1\}\): \(r\) followed by the vertices of the forest in preorder lists every vertex exactly once.
theorem isSpanning_primForest {W : Type*} [LinearOrder W] [Zero W] [Add W]
[Std.Commutative (α := W) (· + ·)] (d : Fin n → Fin n → W) (root : Fin n) :
IsSpanning (List.finRange n) root (primForest d root)
def IsSpanning (V : List α) (r : α) (F : Forest α) : Prop := V.Nodup ∧ (r :: F.preorder).Perm V
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:246
def primForest {W : Type*} [LinearOrder W] [Zero W] [Add W] [Std.Commutative (α := W) (· + ·)]
(d : Fin n → Fin n → W) (root : Fin n) : Forest (Fin n) :=
buildForest (primParents d root) n root
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:331
Uses 5 · Used by 1
TheoremThe tour from Prim's tree is a tour#✓fully proved
For costs \(d(u,v)\) on the vertices \(\{0, \dots, n-1\}\) with values in a linearly ordered type with a zero and commutative addition, and any root \(r\), the list returned by APPROX-TSP-TOUR with Prim's tree for \(d\) and \(r\) is a permutation of \(0, 1, \dots, n-1\): it visits every vertex exactly once.
theorem primTSPTour_isTour {W : Type*} [LinearOrder W] [Zero W] [Add W]
[Std.Commutative (α := W) (· + ·)] (d : Fin n → Fin n → W) (root : Fin n) :
IsTour (List.finRange n) (primTSPTour d root).ret
def IsTour (V H : List α) : Prop := V.Nodup ∧ H.Perm V
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:253
def primTSPTour {W : Type*} [LinearOrder W] [Zero W] [Add W] [Std.Commutative (α := W) (· + ·)]
(d : Fin n → Fin n → W) (root : Fin n) : TimeM ℕ (List (Fin n)) :=
approxTSPTour root (primForest d root)
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:336
Uses 5
TheoremEdge sums over a parent tree#✓fully proved
Let \(p\) be a parent array on the vertices \(\{0, \dots, n-1\}\) in which the root \(r\) has no parent and every chain of parents reaches \(r\), and let \(w\) assign to each unordered pair \(\{u, v\}\) of vertices (possibly \(u = v\)) a value in a commutative additive monoid. Write \(\hat p(u)\) for the parent of \(u\), or \(u\) itself if \(u\) has no parent. Then the sum of \(w(e)\) over the edges \(e\) of the parent graph (distinct \(u\) and \(v\) are adjacent when one is the parent of the other) equals the sum of \(w(\{\hat p(u), u\})\) over the vertices \(u\) of the forest built from \(p\) below \(r\), \(n\) levels deep, listed in preorder.
theorem sum_edgeFinset_eq {M : Type*} [AddCommMonoid M] (ht : ParentTree par root)
(w : Sym2 (Fin n) → M) :
∑ e ∈ (SimpleGraph.fromRel fun u v => par v = some u).edgeFinset, w e =
((buildForest par n root).preorder.map fun u => w s(up par u, u)).sum
structure ParentTree (root : Fin n) : Prop where
root_none : par root = none
reach : ∀ v, ∃ j, (up par)^[j] v = root
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:77
def buildForest : ℕ → Fin n → Forest (Fin n)
| 0, _ => .nil
| k + 1, v => (children par v).foldr (fun c acc => .cons c (buildForest k c) acc) .nil
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:72
def up (v : Fin n) : Fin n := (par v).getD v
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:66
Uses 8 · Used by 1
TheoremAPPROX-TSP-TOUR with Prim's tree is a 2-approximation#✓fully proved
Let \(d\) be a real metric cost on the vertices \(\{0, \dots, n-1\}\) (symmetric, zero on the diagonal, nonnegative, and satisfying the triangle inequality), and let \(r\) be a vertex. Then the cost of the closed tour through the list returned by APPROX-TSP-TOUR with Prim's tree for \(d\) and \(r\) is at most twice the cost of the closed tour through \(H\), for every list \(H\) that visits each of \(0, 1, \dots, n-1\) exactly once.
This is CLRS Theorem 35.2, with the minimum spanning tree computed by Prim.
theorem primTSPTour_two_approx {n : ℕ} {d : Fin n → Fin n → ℝ} (hd : IsMetricCost d)
(root : Fin n) {H : List (Fin n)} (hH : IsTour (List.finRange n) H) :
tourCost d (primTSPTour d root).ret ≤ 2 * tourCost d H
structure IsMetricCost (d : α → α → R) : Prop where
symm : ∀ x y, d x y = d y x
self : ∀ x, d x x = 0
nonneg : ∀ x y, 0 ≤ d x y
triangle : ∀ x y z, d x z ≤ d x y + d y z
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:60
def IsTour (V H : List α) : Prop := V.Nodup ∧ H.Perm V
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:253
def tourCost (d : α → α → R) : List α → R
| [] => 0
| h :: t => pathFrom d h (t ++ [h])
CSLibExt/Algorithms/Lean/Approximation/MetricTSP.lean:72
def primTSPTour {W : Type*} [LinearOrder W] [Zero W] [Add W] [Std.Commutative (α := W) (· + ·)]
(d : Fin n → Fin n → W) (root : Fin n) : TimeM ℕ (List (Fin n)) :=
approxTSPTour root (primForest d root)
CSLibExt/Algorithms/Lean/Approximation/MetricTSPPrim.lean:336
Uses 24
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.