LECTURE 09
BACKTRACKING
Learning Outcomes
Understand the concept of backtracking, and branch
and bound
Use backtracking/branch and bound to solve problem
Introduction
A strategy which construct a solution in a incremental
manner
Can easily be implemented using recursion
Solve one small piece of problem at a time
Try all possible configuration
But each configuration is tried once
To decide among multiple alternatives to the next solution,
recursively evaluates each alternative and choose the
best one
When reach a dead end (or non promising path/node),
backtrack (back to the previous point/parent) to try
another till the solution is found or all configuration is tried
~modified from Depth First Search
Introduction
Famous in solving constraint satisfaction problems
Such as crosswords, Sudoku
Solve problem with a sequence of objects from the
set, where the sequence satisfies some criteria
Guaranty to find all solution to a finite problem in a
bounded amount of time
Prune state space, do not revisit non promising
path/node again
However, worst case is still exponential
Must customise for each individual application
Backtracking VS Dynamic Programming
DP – subsets of a solution are generated
Backtracking – technique for deciding that some
subsets need not be generated
The Concept
Assume that you are in the maze. You do not know the
exact exit path, but just walk in and find the way.
You may turn to a dead end. When that happen, you will
just back to the point where you make the turn
You will backtrack to take the next turn.
This process will repeat until you find the exit path.
The Concept
When size of problem increase, search spaces grows
exponentially
Prune the search space by terminating every search
path when an instant cannot lead to a solution
What to prune?
Remove symmetry
The Concept
Generally:
Each object is represented by an array A[1:n]
Element of the array are from a domain D={d1,d2,
…,dm}
Commonly, D is a finite set of successive
integers
The values of array A must satisfy some
constraints C
Subset Sum Problem ~ A Knapsack
Problem
Given a set of numbers.
All positive integers
S = {s1,s2…..sn}
E.g.: S={1,2,3,4,5,6,7,8,9}
We want to find a subset of numbers which the sum
of these numbers equal the target sum, T
Find every RS where
E.g.: target sum = 17
Subset R includes {s8,s9} or {8, 9}; {2,7,8}; {2,4,5,6}
and so on
Subset Sum Problem ~ A Knapsack
Problem
It could be solved using greedy approach, dynamic
approach and backtracking
Brute force would form all the subsets and find the
sum of each subset but that is computationally
expensive
Backtracking solves with lesser moves
Backtracking ~ Subset Sum Problem
Assumption and considerations
Domain: Set contains non negative values
Constraint: Input/element in the set is unique (no
duplicate value)
To prune the state space:
Sort weights in non-decreasing order before search
Let we be the sum of weights that have been
included up to a node at level i
Node is non promising when we + si+1 > T
Let tot be the total weight of the remaining weights
at a given node
A node is non promising if we+tot<T
Backtracking ~ Subset Sum Problem
Value in node: sum
Set s = [3,5,6,7] T = 15
Inequality below a node represents
termination
Algorithm ~ Subset Sum Problem
Input: set s[ ], the number of elements n, desired sum and weight of the knapsack
Output: result set consisting of elements that can be selected to contain the
desired weight and keeping the weight less than or equal to the weight of the
knapsack
ssp(sum, k, r)
{ //left child
flag[k] :=1; //indicates the include or non-inclusion of an element
if(sum + s[k] + s[k+1] <=m)
write (flag[i:k]);
else if (sum+s[k]+s[k+1]<=m)
ssp(sum+s[k], k+1, r – s[k]);
//right child
if((sum + r + s[k] >= m) and (sum + s[k+1] <= m))
{
flag[k] := 0;
ssp(sum, k+1, r – s[k]);
}
}
Ref source: Bhasin, H. (2015). Algorithms Design and Analysis.
Algorithm ~ Subset Sum Problem
Sum=0, k = 0, r
=15
No items
Put in items k=0 with flag
1
ssp(sum=0+3, 0+1, 15-
3)
Put in items 0 & item k=1
Item 1 with flag 1
ssp(sum = 3+5=8, k = 1+1, 12-
5=7)
sum=8, r=7; check item 2:
Put in item 0, 1 & item k=2 If 8+7+6 > 15 and 8+7 <=15
Item 2 with flag 1 Flag[2] = 0 #exclude item 2
Elseif: 8+6+7 (if include item 2 & ssp(8,2+1=3,7-6)
3)>15
Algorithm ~ Subset Sum Problem
Put in items 0 & item k=1
Item 1 with flag 1
ssp(sum = 3+5=8, k = 1+1, 12-
5=7)
sum=8, r=7; check item 2:
Put in item 0, 1 & item k=2 If 8+7+6 > 15 and 8+7 <=15
Item 2 with flag 1 Flag[2] = 0 #exclude item 2
Elseif: 8+6+7 (if include item 2 & ssp(8,2+1=3,7-6)
3)>15
Proceed to right child (backtrack)
Put in items 0, 1 & item 3
Item 3 with flag 1
No more items
N Queens Problem
A classical chess first proposed by a chess enthusiast
in German: Max Bezzel in 1848 (8 x 8 board)
Improve by Francois-Josept for the more general n x
n board
Goal: place n queens on an n x n chessboard, so that
no two queens are attacking each other
No two queens are in the same row, same column
or same diagonal
A sample solution
by a
mathematician,
Carl Friedrich
Gauss by placing 8
queens.
N Queens Problem
Assumptions and consideration:
Sequence: n positions where queens are placed
Domain: n2 squares on the board will form the set
Constraint: No two queens threaten each other
N Queens Problem
To avoid any threatening, assume the queen is at (5,5), the
threaten area consists of 8 direction (left, right, up, down and
diagonal (4)).
No queen shall be placed in those squares.
Exercise ~ N Queens Problem
Assume that you have a 4 x 4 chess board, with 4
queens, how should you place each of the queen? [0
represents no queen, 1 represents the queen]
N Queens Problem
How about if you have a 3 x 3 chess board? Can the
problem solved?
It is possible that there is no
Ref: Skiena & Revilla, 2003. solution for certain n x n chess
board.
N Queens Problem
To achieve the goal, e.g., we have 8 x 8 chessboard
Possible placement is:
We have 64 square, but we need only 8 squares to
put the 8 queens, so we have:
64*63*62*61*60*59*58*57 ways divide 8!
It is a permutation. How many solution we have?
That is a lot
That is what a DFS will do, check all solution
N Queens Problem
For a safe solution, how many queens can be placed
in a given column?
If we restrict to each row 1, and each column 1, can
we reduce the search space?
Number of set up: 8*8*8*8*8*8*8*8 = 16,777,216
Yes, we can.
This is backtrack manner.
N Queens Problem
How Gauss solve the problem?
Place queens on the board, one row at a time, start
from the top row
To place the rth queen, try all n squares in row r,
from left to right (this process is repeating, can use
a for loop)
If a square is attacked by an earlier queen,
ignore
Otherwise, place a queen
This could be turned into an algorithm (it has a
clear procedure)
Illustration of N Queens Problem by
using Recursion Tree
Complete solution is Total: 92 solutions.
similar to a depth first However, only 12 are non-
search but the isomorphic. The other
different is: ignore solutions can be obtained
non promising state by rotating and/or flipping
N Queens Problem
j represents the
queen
i represents the row
Q(i) represents the square
Q[i] indicates which square in row i contains a queen.
Outer for: consider all possible square to place a queen on row r
Inner for: check the placement, whether the new placement of the
current queen will not be attacked by the previous queens, i.e. r-1
rows
Application of Backtracking:
Hamiltonian Cycle
Application:
Is it possible to visit all cities (vertices) in a graph
exactly once and come back to the starting city
again?
A simple cycle that passes through every vertex of
graph G exactly once.
Hamiltonian Cycle
Do the graphs below have Hamiltonian circuits?
b c a b
a
e
d d c
f B
A
Graph (A) has a Hamiltonian circuit, namely abcdefa
Graph (B) does not have a Hamiltonian circuit, note that any
circuit containing every vertex must contain the edge {a,b}
twice.
Hamiltonian Cycle
A sequence of vertices {v1, v2, v3…vn} such that
No two vi’s are same except the first and the last
, there is direct edge between vi and vi+1
No edge is repeated
vn and vl are directly connected
Solution of Hamiltonian using backtracking
n elements represent the order in which the graph needs to be
traversed
Need to select the first vertex
To select the next vertex, must met the following 3 conditions
There is still a vertex that can be selected
There is a direct edge from the selected vertex to the next
vertex
The set formed so far has less than n vertices
Reference source: Bhasin, 2015.
Hamiltonian Cycle
Let us start from vertex
a
a
Check the vertex
b f adjacent with a, based
on alphabet order, we
visit b first
Visit c
c e
Visit d
d e Visit e
c Visit f and finally a.
e f Trace like DFS.
d f
a b d e
Hamiltonian Cycle
1 1
Reach the
dead end, so
2 3 4 2 3 4 backtrack to
4.
1 3 5 4 is connected to 1 and 5. If we
choose 1, it is the end and no
5 Hamiltonian cycle. Thus, backtrack to
1 4 5
3 and select 5.
2 and 3 have visited, so choose
1 5 4.
2 3 4
2 3 4 1 5
All vertices are visited, and we
have 1 adjacent to 4, so select
1.
The traversal is: 1, 2, 3, 5, 4
Hamiltonian Cycle
1. Algorithm Hamiltonian (r)
2. {
3. while(true)
4. {
5. Nextvalue(r);
6. if (x[r] = 0)
7. { return; }
8. if (r = n)
9. { print(x[1:n]); }
10. else
11. { Hamiltonian(r+1); }
12. }
13. }
Hamiltonian Cycle
1. Algorithm NextValue(r)
2. {
3. while(true)
4. {
5. x[r] := (x[r] + 1) mod (n+1); //next vertex
6. if (x[r] = 0)
7. { return; }
8. if (G[x[r-1], x[r]] ≠ 0)
9. { //is there an edge?
10. for j:=1 to r – 1 step 1 do
11. if(x[j] = x[r])
12. { break; }
13. if(j==r) then //if true, vertex is distinct
14. if((r < n) || ((r = n) && G[x[n], x[1]] ≠ 0))
15. return;
16. }
17. }
BRANCH & BOUND
IMPROVED VERSION OF BACKTRACKING
Branch & Bounds
A more general optimisation technique that applies where
the greedy and dynamic approaches fail
Worst case: exponential time complexities
However, if applied carefully, run reasonable fast on
average
Two important criterion:
Determines which node to expand and when (means
generate the branches)
Determines when an optimal solution has been found
(use bound to decide which branches to prune and
proceed to possible optimal solution)
This design technique still actively being studied and
improved further
Branch & Bounds
Generally:
Set a upper bound or a lower bound as the target
to achieve
It could be the maximum or the minimum target
(local maximum or local minimum)
The most difficult part is to design the bound
function
It works well when the estimation of cost is
almost accurate
Otherwise, it consumes a lot of memory and time
Setting the bound
Lower bound Minimization problem
BEST WORST
Low value High value
Would you explore this state Cost of best
with a bound which costing solution
some x value?
Maximization Upper bound
problem
WORST BEST
Low value High value
Cost of best Would you explore this state
solution with a bound which costing
some x value?
Branch & Bounds VS Backtracking
B&B is an enhancement of backtracking
Applicable to optimisation problem
Always non-convex optimisation problem (means that it
has more than one extremum point (a lot of local
maximum/minimum)
Non-convex optimisation problem may have two
outcome:
It has no solution
It has solution but take a lot of time
Not easy to get a global solution
Most of the machine learning is convex, only one
global solution
But because of deep learning and neural network, it is
non convex
Branch & Bounds VS Backtracking
B&B uses bound (it has a bound function, the most
important part of B&B):
Guide the search through state space
If a node’s bound is not better than the best
solution seen so far, just consider it as non
promising node (means it prunes a solution that is
not good enough)
Could apply DFS or BFS to traverse the tree
Completely search the state space tree to get the
optimal solution
Branch & Bounds VS Backtracking
Backtracking is used to solve discrete constraint
satisfaction problem
If a solution is not guarantee, undo the last choice and
backing up
Use DFS to traverse the tree
Search the state space tree till it gets a solution (not
necessary an optimal solution)
The similar idea between branch and bound and
backtracking is: both try not to search the entire state
space
Example 1: Knapsack problem
EX IN 1
1
EX IN 2 EX IN 2
2 2
IN = include; EX = exclude
In the algorithm, 1 indicate IN, 0 indicate
EX
Example 1: Knapsack problem
Sort all items in decreasing order of ratio (the ratio enables us to
count the upper bound by using Greedy Approach)
Initialize max profit =0
Create an empty queue, Q
Create a dummy node, enqueue to queue, profit and weight are
zeros
While Q is empty:
Extract an item from Q
Compute profit of next level node. If the profit > maxProfit, update
maxProfit
Compute bound of next level node. If bound>maxProfit, add next
level node to Q
Consider the case when next level node is not considered as part
of the solution (EX case) and add node to queue with level as
next, but weight and profit without considering next level nodes
Example 1: Knapsack problem
W = 100, count the ratio, rearrange the items
according to ratio. Start from the highest
ratio.
Ite Weig Valu New Item Weight Value Ratio
m ht e Index(i) No (w) (v) (v/w)
No 1 7 30 60 2
1 40 40
2 2 50 60 6/5
2 50 60
3 1 40 40 1
3 30 10
4 4 10 10 1
4 10 10
5 6 40 20 ½
5 10 3
6 3 30 10 1/3
6 40 20
7 5 10 3 3/10
7 30 60
Objective is to maximize the value, with x = 1
or 0,
Maximize: where N = total no. of items
Example 1: Knapsack problem
First branching: use index 1 as first pivot; UB = upper
bound, B(3)
B(1) =0
=140 =60+60+(1/2)
EX index 1 IN index (40)=140
1 1
2 3
=60+40+10=1 EX index IN index
10 2 2
=60+60+(1/2)
4 EX index 5
=60+40+10+(1/2) (40)=140
3
(20)=120 7 IN index
6
3
=60+60+10+ Cannot
(1/3)(1/2)(10)=135 proceed, so -
999
Assume that items have been sorted according to value (v).
After initialise B(1) = 0, branching to IN and EN where IN = included; EN =
excluded
Example 1: Knapsack problem
=60+60+10+
(1/4)(1/2)(40)=135 6
EX index IN index
4 4
8 9
=60+60+10+
=60+60+(1/2)(1/2)(40) (1/4)(1/2)(40)=135
=130
EX index IN index
5 10 5 11
=60+60+10+ Cannot proceed, so -
(1/3)(1/3)(30)=133(1/3) 999
EX index IN index
6 6
12 13
=60+60+10+ Cannot proceed, so -999
(3/10) (10)=133
Example 1: Knapsack problem
=60+60+10+ 12
EX index IN index
(3/10) (10)=133
7 7
=60+60+10=130 =60+60+10+
(3/10) (10)=133
Through the UB, we can stop to further explore by marking the node as -999.
When we reach the last items, then stop to branch the tree.
Final result: include indexes 1 2 and 3 where B(3) is having the maximal
value.
This is not the only branch and bound method. Next, we look at least cost
method.
Example 2 ~ Job Assignment
Job assignment
One worker performs exactly one job
A set of workers P = {P1, P2, …Pn}
One job is assigned to one worker
A set of jobs J = {J1, J2, …Jn}
Each job has a cost associated to it
Cost Cij represents the cost of assigning Pi with Jj
Total cost of the assignment is minimised:where
Xij = 1 if Pi is assigned to Jj
Xij = 0 otherwise
Example 2 ~ Job Assignment
To get the lower bound could be tedious. You can
travel along the diagonal of each column, and set it as
the lower bound (e.g.: 9+4+1+4= 18) or get the
minimum cost of each column, and use as lower
bound (2+3+1+4=10), or the minimum of each column
without repeat (2+3+5+4=14)
Job 1 Job 2 Job 3 Job 4
Step 1: Generate Person a 9 2 7 8
an initial best Person b 6 4 3 7
solution.
Person c 5 8 1 8
Person d 7 6 9 4
Lower bound (lb): any solution will have at
least 2+3+5+4 (from workers to job)
Example 2 ~ Job Assignment
0
START
lb = 2+3+5+4 =
14
1 2 3 4
a 1 (1st column) a2 a3 a4
lb = 9+3+8+4 = lb = 2+3+5+4 = lb = lb = 8+3+5+6 =
24 14 7+4+5+4=20 22
BEST WORST
14 Cost when state(a=1) = 24.
Explore further?
Cost when state(a=2) = 14.
Explore further?
Example 2 ~ Job Assignment
0
START
lb = 2+3+5+4 =
14
1 2 3 4
a 1 (1st column) a2 a3 a4
lb = 9+3+8+4 = lb = 2+3+5+4 = lb = lb = 8+3+5+6 =
24 14 7+4+5+4=20 22
5 6 7
b1 b 3 b4
lb = lb = lb =
2+6+1+4=13 2+3+5+4=14 2+7+1+7=17
6 6
c 3 c 4
lb = lb =
2+6+1+4=13 2+6+8+9=25
Example 2 ~ Job Assignment
Example 3 ~ Travelling Salesman Problem (TSP)
Give a directed graph G with weight = (V,E), find a path
such that the vij is distinct and the net cost of path is the
minimum.
Visiting each vertex once with starting and end vertex
is the same without repeating the path
This is to obtain a Hamiltonian cycle!
The searching of solution is O(n!) ~exhaustive search,
and we try to reduce that
To minimised the total travel cost:where
Xij = 1 if Pi is moved to Jj
Xij = 0 otherwise
When there is path between two vertices, Cij = infinity.
Reference source: Bhasin,
2015.
Example 3 ~ TSP
1 2 3 4 5
1 ∞ 7 2 10 5
2 2 ∞ 5 10 6
3 4 7 ∞ 5 12
4 3 5 7 ∞ 2
5 12 7 3 4 ∞
Assume that we have the above matrix
Example 3 ~ TSP
1 2 3 4 5
1 ∞ 7 2 10 5 (-2)
2 2 ∞ 5 10 6 (-2)
3 4 7 ∞ 5 12 (-4)
4 3 5 7 ∞ 2 (-2)
5 12 7 3 4 ∞ (-3)
Step 1: reduce the matrix such that each row and each column
has a zero.
Start from row, get the minimum value of each row and subtract.
After minus the highlighted minimum element, we get the
following matrix.
∞ 5 0 8 3
0 ∞ 3 8 4
0 3 ∞ 1 8
1 3 5 ∞ 0
9 4 0 1 ∞
Example 3 ~ TSP
1 2 3 4 5
1 ∞ 5 0 8 3
2 0 ∞ 3 8 4
3 0 3 ∞ 1 8
4 1 3 5 ∞ 0
5 9 4 0 1 ∞
Proceed to column 2 and 4 since these
columns contain no zero. Column 2: the least
element is 3; column 4 is 1. After deduction,
we get the following matrix:
∞ 2 0 7 3
0 ∞ 3 7 4
0 0 ∞ 0 8
1 0 5 ∞ 0
9 1 0 0 ∞
Example 3 ~ TSP
1 2 3 4 5
1 ∞ 2 0 7 3
2 0 ∞ 3 7 4
3 0 0 ∞ 0 8
4 1 0 5 ∞ 0
5 9 1 0 0 ∞
Both row and columns are reduced
now. Compute the deducted values to
get the cost of the root node.
Cost(1)=2+2+4+2+3+3+1= 17
This will set as optimal cost.
Example 3 ~ TSP 1:1
7
1 2 3 4 5
1 ∞ ∞
∞
2 ∞
0 ∞
7 ∞
3 2:19
2 5
3 4
2 ∞
0 ∞ 3 7 4
3 0 ∞
0 ∞ 0 8
4 1 ∞
0 5 ∞ 0
5 9 ∞
1 0 0 ∞
Cost(1,2) = M[1,2](2) + reduction(0) +
cost(1)=2+17=19
Step 2: Find the node that must be visited after the first node
Get the matrix value from 1 to n (cost of edge): M[1,n], where n is the adjacent vertex
Set row 1 and column 2 to ∞
Set M[2, 1] = ∞
Reduce the matrix if the row/column contains no zero
Cost = M[1,n] + reduction cost + cost(parent node)
Example 3 ~ TSP 1:1
7
1 2 3 4 5
1 ∞
∞ ∞
2 ∞
0 ∞
7 ∞
3 5
2:19 3:17
3
0 ∞ ∞ 4
2 3 7 4
3 ∞
0 0 ∞
∞ 0 8
4 1 0 ∞
5 ∞ 0
5 9 1 ∞
0 0 ∞
Cost(1,3) =0 + 0 + cost(1)=17
Example 3 ~ TSP 1:1
7
1 2 3 4 5
1 ∞
∞ ∞
2 ∞
0 ∞
7 ∞
3 5
2:19 3:17
0 ∞ ∞
4
4:24
2 3 7 4
3 0 0 ∞ ∞
0 8
4 ∞
1 0 5 ∞ 0
5 9 1 0 ∞
0 ∞
Cost(1,4) =7 + 0 + cost(1)=24
Example 3 ~ TSP 1:1
7
1 2 3 4 5
1 ∞ ∞
2 ∞
0 ∞
7 ∞
3 2:19 3:17 5
5:20
2 0 ∞ 3 7 ∞
4
4:24
3 0 0 ∞ 0 ∞
8
4 1 0 5 ∞ ∞
0
5 ∞
9 1 0 0 ∞
Cost(1,5) =3 + 0 + cost(1)=20
Thus, select 1-3
and proceed.
Example 3 ~ TSP 1:1
7
1 2 3 4 5
1 ∞ ∞
2 ∞
0 ∞
7 ∞
3 2:19 3:17 5:20
2 ∞
0 ∞ ∞
3 73 40 -4
4:24
3 ∞
∞
0 0
∞ ∞
∞ ∞
0 ∞
8
4 0
1 0
∞ ∞
5 ∞ 0 1-3-2:22
2 4 5
5 8
9 ∞
1 ∞
0 0 ∞
-1
Cost(3,2) =0 + 5 + cost(3)=22
Repeat: Continue from the matrix of 1:3 (with row 1, col 3 and cell [2,1] & [3,1]
are infinity.
Get the matrix value from 3 to n: M[3,n], we start from M[3,2]
Set row 3 and column n to ∞ Why [2,1] need to set
Set M[n,3] to ∞ (no revisit of similar edge) as infinity too?
Because we do not
Reduce the matrix if the row/column contains no zero want the edge 1-3-2
travel back from 2-1.
Cost = M[3,n] + reduction cost + cost(parent node)
Example 3 ~ TSP
When move to the next depth i of the tree, use the
matrix that has obtained from the previous step.
Repeat step 2 till all vertices are done.