ExamplesBy LevelBy TopicLearning Paths
842 Advanced

Branch and Bound

Functional Programming

Tutorial Video

Text description (accessibility)

This video demonstrates the "Branch and Bound" functional Rust example. Difficulty level: Advanced. Key concepts covered: Functional Programming. Backtracking explores the complete search space but doesn't use bounds to prune. Key difference from OCaml: | Aspect | Rust | OCaml |

Tutorial

The Problem

Backtracking explores the complete search space but doesn't use bounds to prune. Branch and bound adds an upper/lower bound computation at each node: if the best possible solution achievable from a partial assignment cannot beat the current best complete solution, prune that entire subtree. This makes branch and bound the algorithm of choice for exact optimization: integer linear programming, traveling salesman problem (with bounds from relaxations), knapsack (with greedy fractional bound), and scheduling optimization. While still exponential in the worst case, good bounds make it practical for real instances that pure backtracking cannot handle.

🎯 Learning Outcomes

  • • Understand the bounding function: optimistic estimate of best achievable value from a partial solution
  • • Implement the branch-and-bound template: branch into children, compute bound, prune if bound ≤ best
  • • Apply to 0/1 knapsack with fractional relaxation bound (greedily pack remaining items fractionally)
  • • Recognize the tradeoff: tighter bounds → more pruning → faster → more expensive to compute
  • • Compare with dynamic programming: DP is exact and polynomial for knapsack; B&B is exact but can prune large trees
  • Code Example

    #![allow(clippy::all)]
    //! Placeholder

    Key Differences

    AspectRustOCaml
    Search strategyDFS (stack-based) or BFSSame options
    Best trackingmut f64 variablefloat ref
    Bounding functionNested fn boundNested let bound or separate
    Priority queueBinaryHeap for best-firstHeap module or priority list
    Sortingsort_by with partial_cmpList.sort with comparison
    Integer variantu64 items and capacityint items

    OCaml Approach

    OCaml's branch-and-bound uses a priority queue (BFS with best-first search) or a recursive DFS. The bound function mirrors the Rust fractional knapsack. OCaml's List.sort sorts items by ratio. The Queue.t or Heap module implements BFS order. Mutable best ref tracks the current best. OCaml's tail-recursive DFS avoids stack overflow for deep trees. The List.fold_left accumulates the bound computation.

    Full Source

    #![allow(clippy::all)]
    //! Placeholder

    Deep Comparison

    OCaml vs Rust: Branch And Bound

    Overview

    See the example.rs and example.ml files for detailed implementations.

    Key Differences

    AspectOCamlRust
    Type systemHindley-MilnerOwnership + traits
    MemoryGCZero-cost abstractions
    MutabilityExplicit refmut keyword
    Error handlingOption/ResultResult<T, E>

    See README.md for detailed comparison.

    Exercises

  • Implement best-first search branch-and-bound using BinaryHeap<Reverse<(NotNan<f64>, State)>> for better pruning order.
  • Apply branch-and-bound to the traveling salesman problem with a minimum spanning tree lower bound.
  • Compare branch-and-bound vs. DP knapsack on instances with 20, 50, 100 items and measure when B&B beats DP.
  • Implement the LP relaxation bound using the minilp crate for tighter bounds on integer programs.
  • Profile the percentage of nodes pruned as a function of bound tightness for random knapsack instances.
  • Open Source Repos