GATE Computer Science & IT · Data Structures & Algorithms
Branch and Bound
State-space search with live nodes, bounding functions, 0/1 knapsack and the travelling-salesman decision to prune.
Six concepts on branch and bound — live nodes and bounds, FIFO/LIFO/LC queues, the 0/1 knapsack state-space, the fractional knapsack bound, the TSP state-space, and a sound (if weak) TSP prune. Running knapsack: items (2,10),(3,14),(4,16) and W=6. Running TSP: four cities with optimum 18.
- GATE Computer Science & IT
- Hard level
- 6 concepts
1Live nodes, E-nodes, and a bounding function
Branch and bound searches a tree of partial answers. Each node is a prefix of a solution — the first few include/exclude decisions, or the first few cities of a tour. A live node has been created and is waiting to be expanded. The E-node (expansion node) is the live node you are expanding now. A dead node will never be expanded.
What kills a node is a bounding function: a number that no feasible completion of that node can beat. For a maximisation problem you kill the node when its bound is no better than the best complete solution already in hand (the incumbent). The bound must be a true limit — if it can be worse than some real completion, you may discard the optimum.
Figure. Static snapshot of statuses, not a playback of the search. The E-node is being expanded; the right child is already dead by bound.
One expansion
- Pick an E-nodeTake one live node (FIFO, LIFO, or least-cost).
- BranchGenerate its children — the next decision's options.
- Bound or killCompute each child's bound. If it cannot beat the incumbent, mark the child dead; otherwise it becomes live.
| Name | Meaning |
|---|---|
| Live | Generated, not yet expanded, still promising |
| E-node | The live node being expanded now |
| Dead | Will not be expanded — bound lost, or infeasible |
| Incumbent | Best complete feasible solution found so far |
A node whose bound cannot beat the incumbent is
- Dead — it will not be expanded
- The new E-node, because a tight bound is interesting
- Live forever, because a bound is only a hint
That is the prune rule. A bound is a hard limit, not a hint. Being tight does not make a losing node the E-node.
2FIFO, LIFO, or least-cost live nodes
The bounding function does not pick which live node becomes the next E-node. That is a separate policy. FIFO expands live nodes in the order they were born — breadth-first. LIFO expands the newest live node — depth-first, close to backtracking. Least-cost (LC) expands the live node whose bound looks best: largest upper bound on a maximisation problem, smallest lower bound on a minimisation problem.
LC often finds a strong incumbent sooner, which then kills more siblings. It is not a different algorithm family; it is a different queue.
Figure. Same bound, three queues. The bars are a qualitative 'how soon a good incumbent arrives' sketch, not a runtime claim.
What the queue changes
- FIFOExpand level by level. Memory holds a whole level of live nodes.
- LIFODive down one path. Memory holds one path plus unexplored siblings.
- Least-costAlways expand the currently most promising bound. Needs a priority queue of live nodes.
| Policy | Next E-node | Closest cousin |
|---|---|---|
| FIFO | Oldest live node | BFS |
| LIFO | Newest live node | DFS / backtracking |
| Least-cost | Best bound among live nodes | Best-first |
Least-cost branch and bound next expands
- The live node with the best bound
- The oldest live node, always
- A random live node, because the bound already decided who dies
LC is best-first on the bound. Oldest-first is FIFO. The bound decides who dies; the queue decides who is expanded among the survivors.
30/1 knapsack: one item per level
The 0/1 knapsack state-space tree has one level per item. The left child of a node includes that item (if it still fits); the right child excludes it. A leaf is a complete packing. Without pruning there are 2^n leaves — the same tree backtracking walks.
The running instance for the rest of this topic: three items (w,v) = (2,10), (3,14), (4,16) and capacity W = 6. Feasible packs are \{1,2\} value 24, \{1,3\} value 26, and the singletons. The 0/1 optimum is 26. Item 3 alone is 16; items 2 and 3 together weigh 7 and do not fit.
Figure. Partial state-space, not the full 2^3 tree. The highlighted leaf is the 0/1 optimum 26. Skip-1 children are omitted so the figure stays readable.
Read one node
- PrefixA node records which of the first i items are taken, the weight so far, and the value so far.
- Left = takeIf item i+1 fits, the left child adds its weight and value.
- Right = skipThe right child leaves weight and value unchanged and moves to the next item.
Feasible leaves
On items (2,10), (3,14), (4,16) and W=6, compute the value of the take-1-take-2 leaf and the take-1-skip-2-take-3 leaf.
- take 1 and 2: weight 2+3=5, value 10+1424 (fits; item 3 cannot join)
- take 1 and 3: weight 2+4=6, value 10+1626
- take 2 and 3: weight 3+4=7infeasible
Pro tip. 26 is the answer we will compare every bound against. 28 will appear next as a fractional bound, not as a packing.
Coding lab. Pack the three-item knapsack runs in the app, with checks on your output.
On this three-item instance the 0/1 optimum is
- 26 — items 1 and 3
- 28 — the fractional packing at the root
- 24 — items 1 and 2, because they leave slack
Items 1 and 3 weigh 6 and value 26. 28 uses a fraction of item 3 and is not 0/1-feasible. 24 is feasible and worse.
4Knapsack bound: fill the rest fractionally
At a knapsack node you already have some weight and value. The remaining items are considered in decreasing v/w order. Take each whole item that still fits; when the next item does not fit, take the fraction of it that fills the leftover capacity. Add that (possibly fractional) extra value to the node's value. The sum is an upper bound on every 0/1 completion of the node.
It is legal as a bound because a fractional packing is at least as good as any 0/1 packing of the same remaining capacity. It is not a feasible 0/1 answer. Prune a node when this bound is \le the incumbent.
Figure. Root bound as a capacity strip: items 1 and 2 fill 5 of 6, then a quarter of item 3 fills the last unit for +4. The terracotta slice is the fraction — not a 0/1 item.
Bound at the root
- Sort by v/wItem 1 has 10/2 = 5; item 2 has 14/3 \approx 4.67; item 3 has 16/4 = 4.
- Take wholesTake item 1 (weight 2, value 10) and item 2 (weight 3, value 14). Capacity left is 1.
- Take a fractionItem 3 needs 4; take 1/4 of 16, which is 4. Bound 10+14+4 = 28.
Fractional upper bound
def bound(level, weight, value, items, W):
# items[level:] already sorted by v/w decreasing
cap = W - weight
b = value
for w, v in items[level:]:
if w <= cap:
cap -= w
b += v
else:
b += v * (cap / w)
break
return bThree bounds on the running instance
Items (2,10),(3,14),(4,16), W=6. Compute the fractional bound at the root, after taking item 1, and after skipping item 1.
- root: take 1, take 2, 1/4 of 310+14+4 = 28
- took 1 (w=2,v=10): same remaining fill28
- skipped 1: take 2 (w=3,v=14), leftover 3, 3/4 of 1614+12 = 26
- once incumbent = 26the skip-1 node has bound 26 → prune (\le incumbent)
Pro tip. After you first reach the feasible leaf 26, the skip-1 branch's bound 26 cannot beat it, so that whole side dies. That is the prune, not a claim that skip-1 is infeasible.
The root bound 28 on this instance means
- No 0/1 packing can exceed 28; 28 itself is not a feasible packing
- The 0/1 answer is 28
- Every node with bound 28 must be expanded to a leaf
28 uses a quarter of item 3. The 0/1 optimum is 26. A bound of 28 only says the node is still interesting until an incumbent of 26 or more arrives.
5TSP: append one unused city
The travelling-salesman state-space tree (from a fixed start) has one level per unvisited city. A node is a simple path that has not yet returned home. A child appends one unused city. A leaf that has used every city is completed by the edge back to the start and becomes a tour.
The running instance: four cities, start at 1, symmetric distances 1-2=2, 1-3=9, 1-4=10, 2-3=6, 2-4=4, 3-4=3. Without pruning there are 3! = 6 tours. Two of them cost 18: 1-2-4-3-1 and 1-3-4-2-1. That 18 is the optimum.
Figure. One optimal tour 1-2-4-3-1 of cost 2+4+3+9=18. Edge lengths are the instance, not to scale.
One branch from city 1
- Children of the startPaths 1-2 (cost 2), 1-3 (cost 9), 1-4 (cost 10).
- Continue 1-2Append 3 (path 8) or 4 (path 6).
- Close a tour1-2-4-3 plus the edge 3-1 of 9 is 18.
Two tours from 1-2
From path 1-2 (cost 2), compute the two complete tours and their costs.
- 1-2-3-4-1 = 2+6+3+1021
- 1-2-4-3-1 = 2+4+3+918
- best of these two18, now the incumbent
Pro tip. TSP here is the optimisation problem — find the shortest tour. The decision version (is there a tour of cost \le K?) is the NP-completeness topic; same tours, different question.
On this 4-city instance the shortest tour from 1 has cost
- 18 — 1-2-4-3-1 (or the reverse 1-3-4-2-1)
- 21 — 1-2-3-4-1
- 2 — the cheapest single edge
Both 18-tours were added in the ledger. 21 is a worse tour. A single edge is not a tour.
6TSP prune: path already worse than the incumbent
TSP is a minimisation problem, so a node dies when no completion can be cheaper than the incumbent. The weakest correct bound is the path cost so far: if that number is already \ge the incumbent, every completion is at least as expensive (edge weights here are positive), and the node is dead.
On the running instance, once the tour of cost 18 is in hand, path 1-4 (cost 10) is still alive under this weak bound, and path 1-2-3 (cost 8) is still alive. A node whose path had already reached 18 or more would die. Stronger textbook bounds — row-and-column reduction of the cost matrix, or path plus a cheap spanning completion — kill more nodes, but only if they are true lower bounds. A bound that can undershoot a real tour can discard the optimum.

Apply the weak bound
- Find any tourExpand 1-2-4-3-1 and record incumbent 18.
- Test a live pathPath 1-3 costs 9. 9 < 18, so the weak bound does not kill it.
- What would dieAny path whose cost is already \ge 18 is dead. Completions of 1-3 happen to be 18 and 29 — none beats 18.
Weak bound versus two completions
Incumbent 18. Path 1-3 costs 9. Compute both completions and say whether the weak bound prunes the node.
- path 1-3cost 9, 9 < 18 → still live
- 1-3-2-4-1 = 9+6+4+1029
- 1-3-4-2-1 = 9+3+4+218
- best completion vs incumbent18, does not beat 18; weak bound did not prune, LC can still skip expanding if you prefer other live nodes
Pro tip. Not pruning is not a failure of the bound. A weak bound is allowed to let a node live; it is not allowed to kill a node that still has a better completion.
With incumbent 18 and positive edge weights, a TSP path of cost 18 is
- Dead under the weak bound — no completion can be cheaper than 18
- The new E-node, because it matches the incumbent
- Alive, because a later edge might have negative cost
Positive leftover edges cannot shrink the cost. Matching the incumbent does not beat it, so a maximise-or-minimise prune of '\ge incumbent' kills the node. These distances are not negative.
Notes
- Branch and bound explores a state-space tree of partial solutions. A live node is generated but not yet expanded; the E-node is the live node being expanded; a dead node will not be expanded.
- A bounding function computes a number no feasible completion of a node can beat. If that bound is no better than the best complete solution already found (the incumbent), the node is killed.
- Search order among live nodes may be FIFO (breadth-first), LIFO (depth-first) or least-cost (expand the live node with the best bound first).
- 0/1 knapsack: each level decides include/exclude one item. The standard bound fills the remaining capacity greedily, taking a fraction of the next item — a bound, not a feasible answer.
- TSP: each level appends one unused city. A weak but sound bound is 'path so far already \ge incumbent'. Stronger bounds (reduced-cost matrices) kill more nodes earlier.
- Branch and bound is not a polynomial algorithm for NP-hard problems. It is an exact search that hopes the bound prunes most of the tree.
Formulas
- Knapsack fractional bound: remaining items sorted by v/w; take whole items while they fit, then a fraction of the next. That value plus the node's value is an upper bound on any 0/1 completion.
- Prune when \mathrm{bound}(\mathrm{node}) \le \mathrm{incumbent} for a maximisation problem (or \ge for a minimisation problem).
- 0/1 knapsack state-space size without pruning: O(2^n) leaves.
- TSP state-space size without pruning: O((n-1)!) tours from a fixed start.
- FIFO / LIFO / LC name the queue of live nodes, not a different bound.
Exam traps & shortcuts
- The fractional knapsack number is a bound, not a feasible 0/1 packing — do not report it as the answer.
- Backtracking is DFS of the same tree without a numeric bound; branch and bound may expand nodes in any live-node order and kills by bound.
- A bound that is not actually a bound (too optimistic in the wrong direction) can drop the optimum. Recompute it on a tiny instance before you trust a prune.
- Finding one complete tour of cost 18 lets you kill every TSP node whose path is already 18 or worse — that weak bound is still correct.
Reference tables
The three-item instance both knapsack concepts share.
| Item | Weight | Value | v/w |
|---|---|---|---|
| 1 | 2 | 10 | 5 |
| 2 | 3 | 14 | 14/3 \approx 4.67 |
| 3 | 4 | 16 | 4 |
The four-city instance both TSP concepts share. A dash is no self-loop.
| 1 | 2 | 3 | 4 | |
|---|---|---|---|---|
| 1 | — | 2 | 9 | 10 |
| 2 | 2 | — | 6 | 4 |
| 3 | 9 | 6 | — | 3 |
| 4 | 10 | 4 | 3 | — |
Recap
Night-before branch-and-bound pegs.
- Parts
- Live node waiting; E-node expanding; dead node pruned; incumbent = best complete so far.
- Queue
- FIFO = BFS, LIFO ≈ backtracking, LC = best bound first. Same bound, different order.
- Knapsack tree
- One item per level, take or skip. This instance's 0/1 opt is 26.
- Knapsack bound
- Fill the rest fractionally by v/w. Root bound 28 is not a feasible packing. Prune if bound \le incumbent.
- TSP tree
- Append an unused city. This instance's shortest tour is 18.
- TSP bound
- Path already \ge incumbent → dead (positive weights). Stronger bounds must still be true lower bounds.
Practise Branch and Bound
Reading is free and needs no account. Practice, mocks and progress live in the app.
- A 6-question practice set that ends the chapter
- 6 quick checks with worked explanations
- Timed mocks scored with the real marking scheme
- Readiness tracked per topic, kept on your device