Part II · trunk A · integer programming · spine

07

Branch and bound

Split the problem, bound each piece with an LP, and throw away every piece that cannot win. What to split on and which piece to look at next decide everything.

needs 05~2 h slides + 3 h lablab: uv run co lab 07

07 · overview

The route

1 · the tree

Branching on a fractional variable, three reasons to prune, the global bound, and the gap.

2 · node selection

Depth-first finds solutions. Best-first proves optimality. What solvers actually ship.

3 · branching

Most-fractional (as good as random), pseudocosts, strong branching, and reliability branching.

4 · the other job

Primal heuristics, reading the gap, and a list of what makes SCIP 6–75× better than yours.

getting around

Words with a dotted underline are glossary terms: click one for its definition. G lists every term in the unit, N shows the notes. Optional extra: interactive figures, linked from the slides they support by a small ▸ chip; skip them freely.

section 1

The tree

Divide the feasible set, and conquer only the pieces that could still contain the optimum.

07 · tree · example

The running example

root LP (2, 2.67) optimum (2, 2) y = 2 y = 3 123 12

Dots: the 7 integer points. Ring: the root LP optimum. Branching on $y$ keeps the strip $y \le 2$ and the empty region $y \ge 3$; the gap between the dashed lines holds no integer point.

$$\begin{aligned}\min\ & -x - 5y \\ \text{s.t. } & 7x + 3y \le 22 \\ & -3x + 3y \le 2 \\ & x, y \ge 0 \text{ integer}\end{aligned}$$

Minimizing $-x - 5y$ means maximizing $x + 5y$: $y$ is worth five times as much.

what the root LP says

Dropping integrality, the optimum is the corner $(2, \tfrac83)$ with value $-\tfrac{46}{3} = -15.33$. That is a lower bound: no integer point does better.

$y = 2.67$ is fractional, so branch on it: $y \le 2$ or $y \ge 3$. The next slide is the whole tree.

07 · tree

LP-based branch and bound

root LP −15.33, y = 2.67 y ≤ 2 LP −12.29, x = 2.29 y ≥ 3 infeasible: prune x ≤ 2: (2, 2) integral −12: incumbent x ≥ 3 LP −4.67 ≥ −12: prune the running example: optimum −12, proved after 5 nodes
  1. Solve the root LP. If its solution is integral, done.
  2. Otherwise pick a fractional $x_j = v$ and create two children (branching): $x_j \le \lfloor v \rfloor$ and $x_j \ge \lceil v \rceil$. Every integer solution is in exactly one child.
  3. Solve each child's LP, and repeat on the open nodes.
prune a node when
  • its LP is infeasible ($y \ge 3$);
  • its LP is integral: it becomes the incumbent if better ($(2,2)$);
  • its LP bound is $\ge$ the incumbent: nothing below it can win ($x \ge 3$).

07 · tree

Two bounds, one gap

Upper bound $U$: the incumbent's objective value, or $+\infty$ before one is found.

Lower bound $L$: the smallest LP bound among open nodes. Every unexplored integer point lies in some open node.

$$L \le z^* \le U, \qquad \text{gap} = \frac{U - L}{|U|}$$

On the example, after the root and its two children: $U = +\infty$, $L = -12.29$. After $(2,2)$ is found: $U = -12$, and the only open node has bound $-4.67 \ge U$, so $L$ jumps to $-12$ and the gap closes to 0.

The solver stops when the gap is 0, or below a tolerance (HiGHS and Gurobi default to a relative gap of $10^{-4}$; SCIP to 0).

two hard jobs

Push $U$ down: find good integer solutions early, so pruning by bound starts early.

Push $L$ up: branch and cut so the open nodes' bounds rise toward $z^*$.

Everything in a MILP solver serves one of these two. A solver log is two columns, "primal bound" and "dual bound", converging.

section 2

Node selection

Which open node to look at next.

07 · selection

Depth-first against best-first

depth-first

Always a child of the last node. Reaches integral leaves quickly, so an incumbent exists early. Small memory. It can spend a long time in a bad subtree.

best-first

Always the open node with the smallest bound. That raises $L$ as fast as possible. The frontier can grow huge, and incumbents come late.

why best-first uses fewest nodes

A node whose bound is below the optimum can never be pruned, so every search must branch on it. Best-first branches on those nodes and (up to ties) nothing else.

full argument in the notes (N)

Lab then, most-fractional branching:

instanceDFSbest
knapsack 22×3 #01 373251
knapsack 22×3 #13 6811 593
UFL 8×20, M = 10C8779

What solvers ship: hybrids of node selection. Dive depth-first from a promising node to find a solution, then jump back to a node with a good bound or a good estimate (best estimate), with periodic plunges.

07 · selection · example

Both orders, on the running example

best-first: 5 nodes
popnodeboundoutcome
1root−15.33branch on $y$
2$y \le 2$−12.29branch on $x$
3$x \le 2$−12integral: $U = -12$
4$x \ge 3$−4.67bound $\ge U$: pruned

It takes the smaller bound first, $-12$ before $-4.67$, finds the optimum there, and the other node dies without being branched.

depth-first: 9 nodes
popnodeboundoutcome
1root−15.33branch on $y$
2$y \le 2$−12.29branch on $x$
3$x \ge 3$−4.67branch on $y$
4$y \le 0$−3.14branch on $x$
5$x \le 3$−3integral: $U = -3$
6$x \le 2$−12integral: $U = -12$

It dives into the last child created, $x \ge 3$, and digs to a poor solution $(3, 0)$ before coming back. Four extra nodes, two of them infeasible children.

section 3

Branching

Which variable to split on. The single biggest influence on tree size.

07 · branching

Most fractional, and why it's weak

Most-fractional branching. Intuition: a variable at 0.5 is "most undecided" (its fractionality is largest), so decide it.

Measured: about as good as branching on a random fractional variable (Achterberg, Koch & Martin 2005, on MIPLIB).

Fractionality says nothing about how much the bound will move. A variable at 0.5 with a zero-cost column changes nothing when fixed, while a variable at 0.9 on a tight constraint can end the subtree.

what a good rule estimates

For each candidate $j$, the bound improvements $\Delta_j^-$ and $\Delta_j^+$ of the two children, combined with the product score

$$\text{score}_j = \max(\Delta_j^-, \varepsilon) \cdot \max(\Delta_j^+, \varepsilon)$$

A product rewards moving both children, and a zero on one side isn't fatal because of the $\varepsilon$.

07 · branching

Strong branching and pseudocosts

strong branching

Compute $\Delta^\pm_j$ exactly: solve both child LPs for each candidate, then branch on the best. The best node counts known, and the most LP solves by far.

Lab totals, best-first: 1 271 nodes but 4 641 LP solves, 3.2 s, against most-fractional's 1 923 nodes and 1.3 s.

pseudocost branching

Estimate $\Delta^\pm_j$ from history: the average gain per unit of fractionality seen when branching on $x_j$ before, times the current fractionality. Costs nothing per node.

Weak at the top of the tree, where there's no history yet. Lab totals: 1 581 nodes, barely better than most-fractional.

reliability branching (Achterberg, Koch & Martin 2005)

Use strong branching on a variable until its pseudocosts are reliable (a few observations each way), then trust the pseudocosts. This is the default rule in SCIP, and the node count of strong branching at roughly the cost of pseudocosts.

07 · branching · example

Scores and pseudocosts, on the running example

a product score from the real tree

At node $y \le 2$ (bound $-12.29$) we branched on $x = 2.29$:

$\Delta^- = -12 - (-12.29) = 0.29$, $\quad \Delta^+ = -4.67 - (-12.29) = 7.62$

score $= 0.29 \times 7.62 = 2.18$

two candidates, given gains
candidate$\Delta^-$$\Delta^+$sumproduct
A0.188.10.8
B2356

A sum prefers A; the product prefers B, which moves both children.

pseudocosts recorded by that tree
branchgain÷ fractional partper unit
$y$ down, at root3.05$\div\ 0.67$4.57
$x$ down0.29$\div\ 0.29$1.00
$x$ up7.62$\div\ 0.71$10.67

Next time $x$ is fractional elsewhere in the tree, with fractional part 0.5, the pseudocost predicts $\Delta^- \approx 0.5 \times 1.00$ and $\Delta^+ \approx 0.5 \times 10.67$, without solving an LP.

$y$ up was infeasible, so no gain was recorded for it.

section 4

The other job, and the gap to SCIP

Finding good solutions early, and what else solvers do.

07 · primal side

Primal heuristics

A good incumbent early lets bound pruning start early. Solvers spend a share of their time on primal heuristics that find one:

  • Rounding: round the LP solution in a way that keeps feasibility where possible (simple rounding, ZI rounding).
  • Diving: fix a variable, re-solve the LP, repeat, down one branch without keeping the tree.
  • RINS (Danna, Rothberg & Le Pape 2005): fix the variables where the incumbent and the LP agree, and solve the small sub-MILP that remains.
  • Feasibility pump (Fischetti, Glover & Lodi 2005): alternate between the LP polytope and the nearest integer point.
in the lab's tree

No heuristics: incumbents only come from integral LP leaves. That is one reason the DFS runs in then are so much larger than SCIP's. SCIP typically has a near-optimal solution before its tree has a dozen nodes.

On the running example, rounding the root LP $(2, 2.67)$ down gives $(2, 2)$, the optimum, before any branching.

Unit 26's local search and unit 19's LNS are the same idea used as stand-alone methods.

07 · the gap

Your factor of shame

instanceyours, bestSCIP bare*SCIPHiGHS
knapsack 22×3 #01578789
knapsack 22×3 #11 039203161208
UFL 8×20, M = 10C754111

"Yours, best": the fewest nodes among your six variants. * SCIP bare: presolve and cuts off. The ratio of your column to SCIP's is the factor of shame.

hypotheses to test
  • Cutting planes raise the root bound (unit 08). Default vs bare SCIP isolates them plus presolve.
  • Presolve tightens bounds and coefficients (units 05, 27).
  • Branching: reliability branching vs yours. Bare SCIP still wins by 2–5×.
  • Heuristics give an early incumbent, and more pruning.
  • Conflict analysis learns from infeasible nodes (the SAT idea of unit 20).

07 · lab

Lab 07 — what you build

about 3 hours · uv run co lab 07 · LPs solved for you
  1. Most fractional and the two children.
  2. The tree: prune, accept incumbents, branch, best-first or DFS, and record pseudocost history.
  3. The product score.
  4. Pseudocost branching from the recorded history.
  5. Strong branching, with its probes counted.
uv run co test 07
uv run co then 07     # the 3x2 matrix, SCIP bare, SCIP and HiGHS default, factor of shame

07 · checkpoint

Done when

checkpoint
  • All five lab steps are ✓.
  • Your strong-branching variant beats your most-fractional variant on node count while losing on wall time, and you can explain that trade-off in terms of LP solves per node.
  • You can say what reliability branching is and why it exists.

Reading

Wolsey, ch. 7.
Achterberg, Koch & Martin, "Branching rules revisited", ORL 33 (2005).
Achterberg (2007), thesis, ch. 5–6 (optional).

Next

08 cutting planes, which test the first hypothesis · 16 DP, where a third exact method meets this one · 31 learns a branching rule for this tree.