Approximation Algorithms: Vertex Cover & TSP
Objective
The P vs NP and reducibility concept ends on a practical punchline: most of the optimization problems that show up in scheduling, routing, and resource allocation are NP-hard, so there is almost certainly no polynomial-time algorithm that finds the exact optimum. Approximation algorithms are the disciplined response to that punchline — instead of giving up on efficiency or falling back to an unbounded heuristic, they trade optimality for a provable, bounded ratio between the returned solution's value and the true optimum's value, while still running in polynomial time. This concept covers the two flagship examples Cormen et al. use to introduce that idea in Chapter 35: APPROX-VERTEX-COVER, a clean 2-approximation for the NP-complete vertex-cover problem, and APPROX-TSP-TOUR, a 2-approximation for the traveling-salesperson problem that only works when the edge costs obey the triangle inequality — and the theorem explaining why that restriction is not optional.
Use Cases
- Reaching for
APPROX-VERTEX-COVERwhenever you need a vertex cover with a provable quality guarantee in polynomial time, rather than searching for an exact optimal cover — which is NP-complete, as established by the sibling P vs NP and reducibility concept. - Recognizing the general proof methodology — find a lower bound on the optimum using a cheaper relaxed structure (a maximal matching for vertex cover, a minimum spanning tree for TSP), then bound the algorithm's output against that lower bound — since the source explicitly notes "we will use this methodology in later sections as well."
- Checking whether your edge-cost function satisfies the triangle inequality (as ordinary Euclidean distance between points in the plane does) before reaching for
APPROX-TSP-TOUR: the 2-approximation guarantee only holds under that assumption. - Recognizing when to stop looking for any ratio-bounded polynomial-time approximation at all: for the general traveling-salesperson problem without the triangle inequality, Theorem 35.3 proves no such algorithm exists for any constant ratio unless P = NP.
Deep Dive
APPROX-VERTEX-COVER: pick an edge, cover both endpoints, repeat
java// Faithful translation of APPROX-VERTEX-COVER(G) (CLRS, Section 35.1).
// remaining models E' as adjacency sets so an edge and everything incident
// to its endpoints can be dropped in O(1) amortized per removed edge,
// giving the O(V + E) running time the source claims.
Set<Integer> approxVertexCover(Map<Integer, Set<Integer>> adjacency) {
Map<Integer, Set<Integer>> remaining = deepCopy(adjacency); // line 2: E' = G.E
Set<Integer> cover = new HashSet<>(); // line 1: C = {}
while (hasAnyEdge(remaining)) { // line 3
int u = anyVertexWithEdge(remaining); // line 4
int v = remaining.get(u).iterator().next();
cover.add(u); // line 5
cover.add(v);
removeAllIncidentEdges(remaining, u); // line 6
removeAllIncidentEdges(remaining, v);
}
return cover; // line 7
}A vertex cover of an undirected graph G = (V, E) is a subset V' ⊆ V such that every edge (u, v) ∈ E has at least one endpoint in V'. The vertex-cover problem asks for a minimum-size such subset; that decision problem is NP-complete, and nobody knows a polynomial-time algorithm that finds an optimal cover. APPROX-VERTEX-COVER sidesteps that by returning a cover that is guaranteed to be at most twice the size of an optimal one, in O(V + E) time using adjacency lists.
The example graph below traces the algorithm on a 6-vertex path a-b-c-d-e-f (edges a-b, b-c, c-d, d-e, e-f). Because the engine's edges are fixed once drawn (they cannot be visually deleted), each step's caption narrates which edges line 6 removes from E' — the persistent visit marks track membership in C, and traverse highlights the edge picked at line 4:
APPROX-VERTEX-COVER returns C = {a, b, c, d, e, f} — all six vertices — while an optimal cover for this path is {b, d, f}, size 3. So here the algorithm returns exactly twice the optimum, which is the worst case Theorem 35.1 allows. The source's own Figure 35.1 runs the same algorithm on a different 7-vertex, 8-edge graph and reports the same shape of result: the algorithm picks edges (b,c), (e,f), and (d,g) in turn, returning C = {b, c, d, e, f, g} (size 6), against an optimal cover {b, d, e} (size 3) — again exactly a factor of 2.
Why the ratio is exactly 2: the maximal matching lower bound
Theorem 35.1 states that APPROX-VERTEX-COVER is a polynomial-time 2-approximation algorithm. The proof does not need to know the size of an optimal cover C* — it only needs a lower bound on it, obtained cheaply:
- Let
Abe the set of edges picked by line 4 across all iterations. No two edges inAshare an endpoint: once an edge is picked, line 6 deletes every other edge incident on its endpoints fromE', soAis a matching — in fact a maximal matching inG(Exercise 35.1-2). - Any vertex cover — in particular an optimal one,
C*— must include at least one endpoint of every edge inA, and since no two edges inAshare an endpoint, no single vertex ofC*can cover two of them. That gives the lower bound|C*| ≥ |A|. - Each iteration of the loop adds exactly 2 new vertices to
C(both endpoints of the picked edge, neither of which was already inC), so|C| = 2|A|exactly. - Combining:
|C| = 2|A| ≤ 2|C*|.
That last step is the whole proof: the algorithm's output is pinned to twice a lower bound on the optimum, and the lower bound comes for free from the fact that the picked edges never overlap. The source calls out this exact pattern — bound the algorithm against a cheap lower-bound structure rather than the (unknown) exact optimum — as a methodology reused throughout the rest of the chapter.
APPROX-TSP-TOUR: build an MST, then walk it
java// Faithful translation of APPROX-TSP-TOUR(G, c) (CLRS, Section 35.2.1).
// Only valid when c satisfies the triangle inequality: c(u,w) <= c(u,v) + c(v,w).
List<Integer> approxTspTour(Graph g, CostFunction c, int root) {
Tree mst = mstPrim(g, c, root); // line 2: minimum spanning tree from root r
List<Integer> tour = new ArrayList<>();
preorderWalk(mst, root, tour::add); // line 3: list each vertex when first visited
return tour; // line 4: the hamiltonian cycle H
}The input is a complete undirected graph G = (V, E) with a nonnegative integer cost c(u, v) on every edge, and the goal is the minimum-cost hamiltonian cycle (tour). APPROX-TSP-TOUR selects a root r, computes a minimum spanning tree T of G from r via MST-PRIM, then returns the tour given by a preorder walk of T (each vertex listed the first time it is encountered). With a simple MST-PRIM implementation the running time is Θ(V²).
Theorem 35.2: when the cost function satisfies the triangle inequality, APPROX-TSP-TOUR is a polynomial-time 2-approximation. The proof reuses the same "cheap lower bound" methodology as vertex cover:
- Deleting any edge from an optimal tour
H*yields a spanning tree, and costs are nonnegative, so the MST's weight lower-bounds the optimal tour:c(T) ≤ c(H*). - A full walk
WofT(visiting a vertex again every time the walk returns to it after a subtree) traverses every tree edge exactly twice, soc(W) = 2·c(T) ≤ 2·c(H*). Wis not itself a tour (it revisits vertices), but the triangle inequality guarantees that deleting a repeated visit to a vertex — going directly from its predecessor to its successor in the walk — never increases cost. Removing every repeat visit fromWleaves exactly the preorder-walk ordering, i.e. the tourHthat the algorithm returns, soc(H) ≤ c(W).- Combining:
c(H) ≤ c(W) ≤ 2·c(H*).
The source's own worked example (Figure 35.2) grows an MST from a root a over 8 points on a grid, whose full walk is a, b, c, b, h, b, a, d, e, f, e, g, e, d, a; collapsing repeat visits gives the preorder tour a, b, c, h, d, e, f, g, with cost about 19.074, against an optimal tour of cost about 14.715 — well within the factor-of-2 bound.
Why no approximation exists without the triangle inequality
Theorem 35.3: if P ≠ NP, then for any constant ρ ≥ 1 there is no polynomial-time ρ-approximation algorithm for the general traveling-salesperson problem (no triangle-inequality assumption). The proof is a reduction from the NP-complete hamiltonian-cycle problem, and it is the general template the chapter uses for proving no good approximation exists:
- Given a graph
G = (V, E)(a hamiltonian-cycle instance), build the complete graphG' = (V, E')with cost functionc(u, v) = 1if(u, v) ∈ E, andc(u, v) = ρ|V| + 1otherwise. - If
Ghas a hamiltonian cycle,(G', c)has a tour of cost exactly|V|. IfGhas no hamiltonian cycle, every tour ofG'must use at least one non-edge, costing at least(ρ|V| + 1) + (|V| - 1) = ρ|V| + |V| > ρ|V|. - That gap —
|V|versus more thanρ|V|— is bigger than the ratioρa hypothesizedρ-approximation algorithmAis allowed to miss by. SoArun on(G', c)must return the cost-|V|tour whenever one exists, and can never return one when it doesn't — which meansAdecides hamiltonian-cycle in polynomial time, contradicting its NP-completeness unlessP = NP.
Since the traveling-salesperson problem stays NP-complete even with the triangle inequality (Exercise 35.2-2), the practical reading is: check whether your cost function satisfies the triangle inequality before investing in a TSP approximation. If it does, APPROX-TSP-TOUR gives a genuine, provable factor of 2. If it doesn't, no constant-ratio polynomial-time approximation exists at all, unless P = NP.
Trade-offs
- Arbitrary edge choice, not greedy-by-degree —
APPROX-VERTEX-COVER's power comes from picking any uncovered edge and taking both endpoints, which is what makes the matching argument work. The source's own Exercise 35.1-3 points out that the seemingly smarter heuristic of repeatedly removing the highest-degree vertex does not guarantee a ratio of 2 — the simple algorithm beats the intuitively-greedy one. - The vertex-cover bound is tight, not just an upper estimate — the proof shows
|C| = 2|A|exactly, not merely≤, so on inputs like the path example above (or the source's own Figure 35.1) the algorithm really does return double the optimum, not just "up to" double. - APPROX-TSP-TOUR's guarantee is conditional on the triangle inequality — without it, Theorem 35.3 rules out any constant-ratio polynomial-time approximation unless P = NP, so the 2-approximation only ever applies to a restricted (if common, e.g. Euclidean-distance) class of instances.
- A provable ratio is not the same as the best practical algorithm — the source explicitly notes that despite its clean 2-approximation ratio,
APPROX-TSP-TOUR"is usually not the best practical choice for this problem," and that other approximation algorithms typically perform much better in practice, without giving up the polynomial-time guarantee.