Abstract
Given an undirected graph with nodes representing people, and an edge between and if and are enemies, find the largest set of people such that no two are enemies. In other words: given an undirected graph, find the largest set of vertices such that no two are connected by an edge.
- Category: Backtracking / Graph Optimization (NP-Hard)
- Input: An undirected graph
- Output: The largest independent set of
- Paradigm: Backtracking — branch on “include this vertex or not,” recursively, refined over three iterations below
- Typical use cases: scheduling/conflict-avoidance problems, the canonical example of squeezing a much better exponential base out of brute-force backtracking via case analysis
Problem Specification
- Instance: Undirected graph .
- Solution Format: Subset of vertices.
- Constraint: No two vertices in the subset are connected by an edge.
- Objective: Maximize the size of the subset.
- Goal: Maximize.
Candidate Strategies / Approaches
Backtracking approach: do exhaustive search locally, but use the constraints to simplify the problem as you go.
- What is a local decision? Do we pick vertex or not?
- What are the possible answers to this decision? Yes or no.
- How do the answers affect the future of the problem?
- If we pick : recurse on the subgraph , and add 1 for (since none of ‘s neighbors can ever be picked alongside ).
- If we don’t pick : recurse on the subgraph .
This one branching rule is the seed for all three algorithm versions below — what changes across MIS1 → MIS2 → MIS3 is when it’s safe to skip computing one of the two branches entirely.
Algorithm Iterations
MIS1 — Naive Backtracking
Algorithm 2 Maximal Independent Set
procedure MIS1()
if then
return
Pick a vertex
In =
Out =
if then
return In
else
return Out
Correctness
- Base Case ():
MIS1correctly returns the empty set. - Inductive Hypothesis: for ,
MIS1correctly returns the maximum independent set of any graph with vertices, for . - Argument:
Inis the best independent set containing ;Outis the best independent set not containing . Every independent set either contains or doesn’t, so the better of the two is the true maximum independent set of .
Time Analysis
Both In and Out cost in the worst case (In removes at least itself — possibly more if has neighbors, but the worst case for the bound is when has no neighbors and only 1 vertex is removed; Out always removes exactly ):
Worst Case for MIS1
When you pick a vertex with no neighbors, the In subproblem only decreases by 1 (same as Out) — but do we actually need to consider Out at all in that case? Shouldn’t we just pick ? More generally: if a vertex has no neighbors, the In case is always at least as good as the Out case — including an isolated vertex can never conflict with anything else, so there’s no reason to ever leave it out.
MIS2 — Skip Out When
Algorithm 3 Maximal Independent Set
procedure MIS2()
if then
return
Pick a vertex
In =
if then
return In
Out =
if then
return In
else
return Out
Time Analysis
(This is exactly the Fibonacci recurrence — , the golden ratio.) A huge improvement from the initial approach.
Worst Case for MIS2
When you pick a vertex with exactly one neighbor, the In subproblem only decreases by 2 (removing and its one neighbor) — but do we actually need to consider Out here either? Shouldn’t we just pick ? More generally: if a vertex has one neighbor, the In case is always at least as good as the Out case. This one takes a bit more convincing than the degree-0 case.
Claim: suppose is a vertex of with only one neighbor, . Suppose is an independent set that does not include . There is an independent set that does include , with .
Proof: consider two cases based on whether contains (v’s only neighbor):
- Case 1 — does not contain : let . Since doesn’t contain ‘s only neighbor, adding can’t create a conflict, so is valid, and .
- Case 2 — contains : let . no longer contains ‘s only neighbor, so by the validity of elsewhere, is valid, and .
Either way, , so including is never worse than excluding it.
MIS3 — Also Skip Out When
Algorithm 4 Maximal Independent Set
procedure MIS3()
if then
return
Pick a vertex
In =
if or then
return In
Out =
if then
return In
else
return Out
Time Analysis
Time & Space Complexity Analysis
Summary Across Iterations
| Version | Skips Out when | Recurrence | Bound |
|---|---|---|---|
| MIS1 | Never | ||
| MIS2 | |||
| MIS3 |
The pattern is clear: proving that low-degree vertices are always safe to include (never worse than excluding) lets you skip computing an entire recursive branch for them, and handling more and more low-degree cases keeps shrinking the exponential base. The best known MIS algorithm is around , due to Robson, building on Tarjan and Trojanowski — it does much more elaborate case analysis for small-degree vertices, following exactly this same pattern to its logical extreme.
Space
Each version’s space is dominated by recursion depth, which is in the worst case (one vertex removed per level in the shallowest branch).
Drawbacks / Constraints
- Still exponential. Maximal (maximum) Independent Set is NP-hard, so no polynomial-time algorithm is expected for the general case, no matter how much low-degree case analysis is added.
- Diminishing returns, rapidly increasing complexity. Going from MIS1 → MIS2 → MIS3 required proving a genuine exchange-argument-style claim just to handle degree-1 vertices; Robson’s result needs “much more elaborate case analysis” for small-degree vertices, illustrating that each further improvement costs substantially more implementation and proof effort for a shrinking marginal gain.
- Only helps low-degree vertices. This whole line of refinement exploits the fact that a low-degree vertex barely shrinks the graph on the
Outbranch — it doesn’t directly help with dense graphs where most vertices have high degree.
Toward Dynamic Programming
Each
MIScall recurses on an induced subgraph obtained by deleting a small set of vertices — but which specific subgraph you get depends on the sequence of choices made to get there, so in general graphs there’s no small, reusable set of subproblems to memoize. This is exactly the boundary case that makes Dynamic Programming work beautifully on some backtracking problems (where subproblems collapse to a polynomial-size, reusable set — e.g. “the best solution using only elements ”) but not on others like general-graph MIS, where the reachable subgraphs don’t collapse that way.The exception that proves the rule: restrict the input to a tree, and the subproblems do collapse — each vertex’s subtree is a clean, reusable subproblem, since subtrees never overlap. See Maximum Independent Set in Trees for the resulting DP solution, a direct contrast to this note’s exponential general-graph result.