1. Introduction to Backtracking
1.1 Key Concepts
1.2 General Backtracking Template
function BACKTRACK(state):
if IS_SOLUTION(state):
PROCESS_SOLUTION(state)
return
for each choice in GET_CHOICES(state):
if IS_PROMISING(state, choice):
MAKE_CHOICE(state, choice)
BACKTRACK(state) // Recurse
UNDO_CHOICE(state, choice) // Backtrack
2. N-Queens Problem
2.1 Constraints
- Row constraint: Only one queen per row
- Column constraint: Only one queen per column
- Diagonal constraint: No two queens on the same diagonal
2.2 Promising Function
For placing queen in row k at column j, check if it conflicts with queens in rows 1 to k-1:
function IS_PROMISING(k, col[], j):
for i = 1 to k-1:
// Check column conflict
if col[i] == j:
return false
// Check diagonal conflict
// |row difference| == |column difference| means same diagonal
if |i - k| == |col[i] - j|:
return false
return true
2.3 N-Queens Algorithm
function N_QUEENS(k, n, col[]):
// k = current row, n = board size, col[i] = column of queen in row i
if k > n:
// All queens placed successfully
PRINT_SOLUTION(col)
return
for j = 1 to n:
if IS_PROMISING(k, col, j):
col[k] = j // Place queen in row k, column j
N_QUEENS(k+1, n, col) // Try to place in next row
// Backtracking happens automatically on return
State Space Tree for 4-Queens
Root (place Q in row 1)
/ | | \
col=1 col=2 col=3 col=4
| | | |
Row 2: Row 2: Row 2: Row 2:
/|\ /|\ /|\ /|\
(✗col 1,2) (✗col 1,2,3) (✗col 2,3,4) (✗col 3,4)
col=3,4 col=4 col=1 col=1,2
Legend: ✗ = pruned (conflict), continues where promising
Path to Solution 1: Row1=col2 → Row2=col4 → Row3=col1 → Row4=col3
Path to Solution 2: Row1=col3 → Row2=col1 → Row3=col4 → Row4=col2
Solution 1: col[] = {2, 4, 1, 3}
Queens at: (1,2), (2,4), (3,1), (4,3)
Solution 2: col[] = {3, 1, 4, 2}
Queens at: (1,3), (2,1), (3,4), (4,2)
2.4 Time Complexity
| Aspect | Complexity |
|---|---|
| Worst Case (no pruning) | O(n!) |
| With effective pruning | Much better in practice |
| Space | O(n) for recursion stack + O(n) for col array |
3. Sum of Subsets Problem
3.1 Promising Function
A node is promising if:
- Current sum + remaining elements ≥ M (can still reach M)
- Current sum + next element ≤ M (won't exceed M)
function SUM_OF_SUBSETS(i, weight, total):
// i = current index, weight = current sum, total = sum of remaining elements
// Global: W[] = weights, n = size, M = target sum, x[] = solution vector
if IS_PROMISING(i, weight, total):
if weight == M:
PRINT_SOLUTION(x)
else:
// Include W[i+1]
x[i+1] = 1
SUM_OF_SUBSETS(i+1, weight + W[i+1], total - W[i+1])
// Exclude W[i+1]
x[i+1] = 0
SUM_OF_SUBSETS(i+1, weight, total - W[i+1])
function IS_PROMISING(i, weight, total):
return (weight + total >= M) AND
(weight == M OR weight + W[i+1] <= M)
Given: W = {2, 7, 8, 9, 15}, M = 17, Total = 41
(0, 0, 41)
Include 2? / \ Exclude 2?
/ \
(1,2,39) (1,0,39)
/ \ / \
Include 7 Excl 7 Inc 7 Excl 7
/ \ / \
(2,9,32) (2,2,32) (2,7,32) (2,0,32)
/ \ / \ / \ / \
Inc 8 Exc Inc 8 Exc Inc 8 Exc Inc 8 Exc
(17!✓) ... (10) ... (15) ... (8) ...
↓ ↓
(3,10,24) (3,15,24)
↓ ↓
Inc 9 Inc 9
(19>M)✗ (24>M)✗
Exc 9 Exc 9
(3,10,15) (3,15,15)
↓ ↓
Inc 15 Inc 15
(25>M)✗ (30>M)✗
Exc 15 Exc 15
(10≠M)✗ (15≠M)✗
SOLUTION PATH 1: Include 2, Include 7, Include 8
Weight: 2+7+8 = 17 ✓
x = {1, 1, 1, 0, 0}
Continue exploring other branches...
SOLUTION PATH 2: Include 8, Include 9
Need to trace: Exclude 2, Exclude 7, Include 8, Include 9
Weight: 8+9 = 17 ✓
x = {0, 0, 1, 1, 0}
Two Solutions Found:
Sum = 2 + 7 + 8 = 17 ✓
Sum = 8 + 9 = 17 ✓
Pruning Examples:
- At (2,9,32): Include 8 gives sum=17=M → SOLUTION!
- At (3,19,15): 19 > 17, prune this branch
- At some nodes: If sum + remaining < M, prune (can't reach M)
3.2 Time Complexity
| Aspect | Complexity |
|---|---|
| Worst Case | O(2ⁿ) - binary tree of height n |
| With pruning | Much better in practice |
| Space | O(n) |
4. Graph Coloring Problem
4.1 Algorithm
function M_COLORING(k, color[], n, m, graph):
// k = current vertex, m = number of colors available
// color[i] = color assigned to vertex i
if k > n:
PRINT_SOLUTION(color)
return true
for c = 1 to m:
if IS_SAFE(k, c, color, graph):
color[k] = c
if M_COLORING(k+1, color, n, m, graph):
return true
color[k] = 0 // Backtrack
return false
function IS_SAFE(k, c, color[], graph):
for each neighbor v of k:
if color[v] == c:
return false
return true
Graph: Solution (R=Red, G=Green, B=Blue):
1---2 1(R)---2(G)
|\ /| | \ / |
| X | → | X |
|/ \| | / \ |
3---4 3(G)---4(B)
Assignment: color[] = {R, G, G, B}
- Vertex 1: Red (no conflicts)
- Vertex 2: Green (adjacent to 1-Red, OK)
- Vertex 3: Green (adjacent to 1-Red, 4-Blue, OK; NOT adjacent to 2)
- Vertex 4: Blue (adjacent to 2-Green, 3-Green, OK)
4.2 Chromatic Number
The chromatic number χ(G) is the minimum number of colors needed to color graph G. Finding the chromatic number is NP-Hard.
4.3 Time Complexity
O(mⁿ) in worst case - trying m colors for each of n vertices
5. Hamiltonian Cycles
5.1 Algorithm
function HAMILTONIAN_CYCLE(k, path[], visited[], n, graph):
if k == n:
// Check if last vertex connects back to first
if graph[path[k-1]][path[0]] == 1:
PRINT_CYCLE(path)
return true
return false
for v = 1 to n:
if IS_SAFE(v, k, path, visited, graph):
path[k] = v
visited[v] = true
if HAMILTONIAN_CYCLE(k+1, path, visited, n, graph):
return true
// Backtrack
visited[v] = false
return false
function IS_SAFE(v, k, path[], visited[], graph):
// Check if v is adjacent to previous vertex
if graph[path[k-1]][v] == 0:
return false
// Check if v is already visited
if visited[v]:
return false
return true
Graph: Hamiltonian Cycle:
1 --- 2 1 → 2 → 3 → 5 → 4 → 1
| / |
| / | Path visits each vertex once
| / | and returns to start
4 --- 3 --- 5
Adjacency Matrix:
1 2 3 4 5
1 [ 0 1 0 1 0 ]
2 [ 1 0 1 1 0 ]
3 [ 0 1 0 1 1 ]
4 [ 1 1 1 0 0 ]
5 [ 0 0 1 0 0 ]
5.2 Hamiltonian Path vs Cycle
- Hamiltonian Path: Visits every vertex exactly once (no return)
- Hamiltonian Cycle: Visits every vertex exactly once AND returns to start
5.3 Time Complexity
O(n!) - factorial time in worst case (NP-Complete problem)
6. Introduction to Flow Networks
6.1 Key Concepts
Flow cannot exceed edge capacity.
Σf(u,v) = Σf(v,w) for all v ∈ V - {s, t}
10
A ───────► B
↗ │
8 │ 5
↗ │
S ▼
↘ D ────► T
10 ↗ ↗
↘ 8 10
► C ──►
15
Edge notation: capacity (e.g., S→A has capacity 8)
Flow value shown as flow/capacity (e.g., 5/10)
6.2 Residual Network
• Forward edge: capacity = c(u,v) - f(u,v) (remaining capacity)
• Backward edge: capacity = f(u,v) (can reduce flow)
6.3 Augmenting Path
7. Ford-Fulkerson Method
7.1 Algorithm
- Initialize flow f(u,v) = 0 for all edges
- While there exists an augmenting path p from s to t in Gf:
- Find bottleneck capacity b = min{cf(u,v) : (u,v) in p}
- Augment flow along path p by b
- Update residual network Gf
- Return total flow
function FORD_FULKERSON(G, s, t):
Initialize flow f to 0 for all edges
max_flow = 0
while EXISTS_PATH(s, t) in residual network Gf:
// Find augmenting path using BFS/DFS
path = FIND_AUGMENTING_PATH(Gf, s, t)
// Find bottleneck (minimum residual capacity on path)
bottleneck = MIN(cf(u,v) for all (u,v) in path)
// Augment flow along path
for each edge (u,v) in path:
if (u,v) is forward edge:
f(u,v) += bottleneck
else: // backward edge
f(v,u) -= bottleneck
max_flow += bottleneck
return max_flow
10
A ────────► B
↗ │
10 │ 10
↗ │
S ▼
↘ T
10 ↗
↘ 10
► C ────►
10
Iteration 1:
- Path: S → A → B → T
- Bottleneck: min(10, 10, 10) = 10
- Push flow: 10
- Total flow: 10
Iteration 2:
- Path: S → C → T
- Bottleneck: min(10, 10) = 10
- Push flow: 10
- Total flow: 20
Iteration 3: No more augmenting paths (edges S→A and S→C are saturated)
7.2 Edmonds-Karp Algorithm
Edmonds-Karp is Ford-Fulkerson using BFS to find augmenting paths. This guarantees finding the shortest augmenting path each time.
7.3 Time Complexity
| Algorithm | Time Complexity |
|---|---|
| Ford-Fulkerson (general) | O(E × max_flow) |
| Edmonds-Karp (BFS) | O(V × E²) |
8. Applications of Flow Networks
8.1 Bipartite Matching
Find maximum matching between two sets (e.g., jobs to workers). Model as flow network: source connects to one set, sink to other, all capacities = 1.
8.2 Network Connectivity
Find minimum cut (minimum edges to remove to disconnect s from t). By Max-Flow Min-Cut theorem: max flow = min cut.
8.3 Real-World Applications
- Network routing: Maximize data flow through networks
- Transportation: Optimize shipping routes
- Project scheduling: Resource allocation
- Image segmentation: Computer vision applications
- Sports scheduling: Determining playoff possibilities
9. Practice Questions
See Section 2 for complete solution with state-space tree and both solutions.
Solutions: {2,4,1,3} and {3,1,4,2}
See Section 3 for complete solution with state-space tree.
Solutions: {2,7,8} and {8,9}
See Section 4. Key points:
- Try coloring vertices one by one
- For each vertex, try all m colors
- Check if adjacent vertices have different colors
- Backtrack if no valid color found
See Section 7 for algorithm and example.
Key steps:
- Initialize all flows to 0
- Find augmenting path (BFS/DFS)
- Find bottleneck on path
- Augment flow by bottleneck
- Repeat until no augmenting path
Key Points Summary
- Backtracking: Build solution incrementally, prune invalid branches
- N-Queens: 4-Queens has exactly 2 solutions: {2,4,1,3} and {3,1,4,2}
- N-Queens promising: Check column and diagonal conflicts
- Sum of Subsets {2,7,8,9,15}, M=17: Solutions are {2,7,8} and {8,9}
- Graph Coloring: Try colors 1 to m, check adjacent vertices
- Hamiltonian: Visit all vertices exactly once, return to start
- Flow Network: Capacity constraint + Flow conservation
- Augmenting Path: Path from s to t in residual network
- Ford-Fulkerson: Find augmenting paths, push bottleneck flow
- Max-Flow = Min-Cut (theorem)