A subset of Complete Search

Idea

Backtracking uses a decision-tree based philosophy, where in one branch, we make a decision, and in the other binary branch, we do something different

Identification

Use for:

  • Constraint satisfaction problems, when you need to build a solution step-by-step and satisfy certain conditions.
  • Search problems (large solution space but invalid branches can be pruned early)
  • Multiple solutions (Explore all possible valid solutions)
  • Generate all valid combinations or permutations under constraints

Don’t confuse with Dynamic Programming which can be used to solve problems without overkilling. If there is a single optimal solution, DP might be better.

Has two parts:

  • Backtracking
  • Pruning the search

Backtracking starts with an empty solution and extends the solution step by step.

Steps to Solve

  • Define decision space
  • Define what a state means
  • Decide how to recursively move forward with this choice
  • Check if the state is invalid
    • Determine constraints (when do we prune?)
    • If true, backtrack
  • Determine goal condition
  • Repeat until all possibilities are explored, or a solution is found

A mental model

Each look iteration should start using the same prefix, use a fresh DS per branch and don’t reuse it for siblings

From ChatGPT…

Backtracking(path):
    if goal(path):
        record path
        return
    
    # This is choosing what element comes next
    for choice in choices:
        apply(choice)
        if is_valid(path):
            Backtracking(path)
        undo(choice)

^^ Make sure to follow this model rather than the Dynamic Programming take / leave choice model which will lead to a 2^n solution. Doing it this way leads to a wider tree. Anything we skip over in the for loop here is implicitly a “leave” choice.