A 0/1 knapsack with 40 items has 2^40 candidate subsets; a travelling-salesman tour over 15 cities has 14!/2 orderings. Enumerating every configuration to find the single best one is exponential and rarely finishes. Branch-and-bound searches the same space but attaches a bound to every partial configuration — an optimistic estimate of the best objective any completion of it could reach — and discards a whole subtree the moment its bound cannot beat the best complete solution already found.

That pruning is valid only under one precondition: the bound must be optimistic. For a maximisation problem it must never fall below the true best achievable in the subtree; for minimisation it must never rise above it. A bound that leans in the pessimistic direction can throw away the subtree that held the optimum. A bound so loose it never clears the best-so-far leaves plain exponential enumeration.

Core condition: an optimisation objective + a cheap bound from a relaxation that never underestimates a subtree’s true optimum → prune any subtree whose bound cannot beat the best complete solution so far (the incumbent) → exact search that in practice touches a fraction of an exponential tree.

The step that carries the whole idea is a single bound comparison that erases a subtree before it is expanded.

Visualization pending

Planned StepTrace: a search-tree card showing each node’s bound against the running incumbent, where a subtree whose bound cannot beat the incumbent is pruned unexplored. No matching renderer exists in engine.js yet.

Why a subtree can be discarded

Branch-and-bound turns on four moving parts:

  • Branch — split the problem at a decision point into disjoint subproblems (item i is in the knapsack vs out), so the partial configurations form a search tree.
  • Bound — at each node, compute an optimistic estimate of the best objective any completion below it could reach. For maximisation this is an upper bound; for minimisation a lower one.
  • Incumbent — the best complete solution seen so far, and the yardstick every bound is measured against.
  • Prune / select — if a node’s bound is no better than the incumbent, discard its whole subtree; otherwise expand it and pick the next live node to visit.

The correctness of the discard rests on the optimism of the bound. For maximisation, “optimistic” means the bound is the true best of every completion in the subtree. So if bound ≤ incumbent, then every completion is ≤ incumbent, and none of them can improve the answer — the subtree can be removed unexplored without risking the optimum. Minimisation reverses the inequality.

This is the same optimism requirement as A* Search’s admissibility condition: a guided tree search stays correct only while its estimate errs in the optimistic direction and never lies pessimistically. Branch-and-bound is that same idea applied to the decision tree of an optimisation problem, with the bounding function playing the role of the heuristic. It is why an LP relaxation is a safe bound — an optimal fractional solution can only meet or exceed the integer optimum, so ignoring integrality never under-shoots.

Exploration order

Every live (unpruned, unexpanded) node is a candidate to visit next, and the order changes how fast a strong incumbent appears — which in turn changes how much gets pruned.

  • Best-first keeps live nodes in a priority queue ordered by bound and always expands the most promising one. It tends to certify the optimum with the fewest expansions, but the queue can hold exponentially many live nodes, so memory is the binding constraint.
  • Depth-first dives to a complete solution quickly in O(depth) memory, like Backtracking. That early incumbent immediately starts pruning siblings, though the dive can waste effort in regions best-first would have skipped.

A good early incumbent raises the bar every later bound must clear, so more subtrees fall on a single comparison. Solvers exploit this by seeding the incumbent with a fast heuristic — often a greedy solution — before the exact search starts.

Complexity

Let n be the number of decisions (the tree depth) and b the cost of computing one bound.

CaseTimeAuxiliary spaceCause
BestO(n · b)O(n)A strong early incumbent and a tight bound prune every sibling; the search follows essentially one root-to-leaf path.
Averageinstance-dependent, ≪ 2ⁿO(n)The bound rejects most subtrees; no closed form — it depends on how tightly the relaxation tracks the objective.
WorstO(2ⁿ · b)O(n)A loose or non-discriminating bound prunes nothing; every node is expanded, as in brute-force enumeration.

The table describes depth-first branch-and-bound over an n-decision binary tree (0/1 knapsack), so auxiliary space is the O(n) recursion stack. Best-first exploration keeps live nodes in a priority queue instead of a stack, so its auxiliary space grows with the frontier — up to O(2ⁿ) nodes — even though it usually expands the fewest nodes to certify the optimum. A permutation problem such as TSP has an n! tree in place of 2ⁿ. In every case the worst case is exponential: branch-and-bound is exact search that improves the constant factor and the typical case, never the complexity class.

When the bound stops helping

A non-optimistic bound returns a wrong answer, silently. Suppose a maximisation subtree’s true best is 90 but the bound reports 78, and the incumbent is 80. The subtree is pruned, its 90 is never found, and the search halts reporting 80 as proven optimal. Nothing flags the error — the optimality certificate is simply false. The defence is to derive the bound from a relaxation that provably dominates the objective (an LP relaxation that ignores integrality), even when that makes the bound looser.

A bound too loose to discriminate degenerates to brute force. “Assume every remaining item is taken at full value with no weight limit” is optimistic and valid, but it exceeds the incumbent at nearly every node, so nothing is pruned and the frontier never shrinks below the full 2ⁿ tree. Validity keeps the answer correct; tightness is what decides the practical runtime, and the two goals pull against per-node cost.

Best-first exploration exhausts memory before time. On a hard instance the priority queue accumulates exponentially many live nodes and the process runs out of RAM long before it runs out of clock. Depth-first or iterative-deepening branch-and-bound bounds space to O(depth), at the cost of re-expanding nodes or losing some global pruning quality.

Reference drawer

Questions

References