Branch & Bound
Imagine you're shopping for the cheapest flight with a layover. You're at the airport considering Route A (New York → Chicago → LA) and Route B (New York → Dallas → LA). Before you even book the leg to Chicago, you check: "What's the absolute minimum the rest of this route could cost?" If even the best-case completion of Route A is more expensive than a complete Route B you already found — skip Route A entirely.
That's Branch and Bound: backtracking upgraded with a bounding function that estimates the best possible outcome of any partial solution. If the best possible outcome can't beat what you've already found, prune the whole branch — don't go there.
The two parts of the name
Branch — split the problem into sub-choices, just like backtracking builds a decision tree.
Bound — for each partial solution, compute a bound: the best possible objective value achievable by completing it. For minimization, this is a lower bound. For maximization, an upper bound.
The pruning rule for minimization: if lower_bound(node) ≥ best_complete_solution_so_far, prune — nothing in this subtree can improve the current best.
Traversal strategies
The order you expand nodes dramatically affects how quickly you find a good solution to tighten the bound:
Depth-first (stack): finds complete solutions quickly, tightening the bound early. Memory-efficient. May explore poor branches before good ones.
Best-first (priority queue): always expands the node with the best (lowest) bound — guaranteed to find the optimal solution with fewest nodes explored. Downside: may require exponential memory.
In practice, best-first with a good bounding function is dramatically faster than alternatives.
0/1 Knapsack — worked example
Branch on each item: include it or skip it. The upper bound for a partial solution: take the value accumulated so far, then greedily fill remaining capacity with the fractional knapsack solution on remaining items (allow breaking items). Since fractional filling is always at least as good as 0/1 filling, this is a valid upper bound. If this upper bound is below the best complete solution found, prune.
With items sorted by value-per-weight ratio, the fractional bound is tight, and pruning is aggressive.
Traveling Salesman Problem
A lower bound for a partial TSP tour: (cost of edges chosen so far) + (minimum spanning tree of unvisited cities). This underestimates the remaining cost — a valid lower bound. When this lower bound exceeds the best complete tour found, prune. With tight bounds, Branch and Bound solves TSP instances with hundreds of cities exactly — though worst case stays exponential.
When to use Branch and Bound
Use it when you need a provably optimal answer and the problem instance is small enough. For larger instances: approximation algorithms give polynomial-time answers within a guaranteed ratio of optimal; dynamic programming works when the problem has suitable substructure; heuristics are fast with no guarantee. The quality of the bounding function is everything — poor bounds mean near-exhaustive search; tight bounds can tame surprisingly large instances.