0% found this document useful (0 votes)
2 views47 pages

Chapter 02

The document discusses recursion, backtracking, and branch-and-bound algorithms in computer science, providing examples and algorithms for various combinatorial problems. It explains recursive procedures, memoization, and the backtracking algorithm for generating configurations, including binary sequences, combinations, and permutations. Additionally, it covers the branch-and-bound method for solving optimization problems, specifically detailing the Traveling Salesman Problem.

Uploaded by

ommessuss
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views47 pages

Chapter 02

The document discusses recursion, backtracking, and branch-and-bound algorithms in computer science, providing examples and algorithms for various combinatorial problems. It explains recursive procedures, memoization, and the backtracking algorithm for generating configurations, including binary sequences, combinations, and permutations. Additionally, it covers the branch-and-bound method for solving optimization problems, specifically detailing the Traveling Salesman Problem.

Uploaded by

ommessuss
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Recursion, Backtracking and

Branch-and-Bound
Pham Quang Dung and Do Phan Thuan

Computer Science Department, SoICT,


Hanoi University of Science and Technology.

August 15, 2016

1 / 47
Recursive procedures

A procedure calls itself


Basic cases: the results are computed trivially

1 int fact ( int n ){


2 if ( n <= 1) return 1;
3 return n * fact (n -1);
4 }
5 int C ( int k , int n ){
6 if ( k == n || k == 0) return 1;
7 return C (k -1 ,n -1) + C (k ,n -1);
8 }

2 / 47
Recursion and Memoization
Procedures with the same parameters may be called several times
A procedure with a given set of parameters is triggered for the first
time is executed, and the results will be stored into memory
Later on, if that procedure with the same set of parameters is
triggered, the procedure will not execute. Rather, the results of that
procedure available in the memory will be returned directly
C(3,5)

C(2,4) C(3,4)

C(1,3) C(2,3) C(2,3) C(3,3)

C(0,2) C(1,2) C(1,2) C(2,2) C(1,2) C(2,2)

C(0,1) C(1,1) C(0,1) C(1,1) C(0,1) C(1,1)

3 / 47
Recursion and Memoization

1 public class Ckn {


2 private int [][] M ;
3 public int C ( int k , int n ){
4 if ( k == 0 || k == n ) M [ k ][ n ] = 1;
5 else if ( M [ k ][ n ] < 0){
6 M [ k ][ n ] = C (k -1 ,n -1) + C (k ,n -1);
7 }
8 return M [ k ][ n ];
9 }
0 public void test (){
1 M = new int [100][100];
2 for ( int i = 0; i < 100; i ++)
3 for ( int j = 0; j < 100; j ++)
4 M [ i ][ j ] = -1;
5
6 System . out . println ( C (15 ,30));
7 }
8 }

4 / 47
Introduction

List all configurations satisfying some given constraints


I permutations
I subsets of a given set
I etc.
A1 , . . . , An are finite sets and X = {(a1 , . . . , an ) | ai ∈ Ai , ∀1 ≤ i ≤ n}
P is a property on X
Generate all configurations (a1 , . . . , an ) having P

5 / 47
Introduction

In many cases, listing is a final way for solving some combinatorial


problems
Two popular methods
I Generating method (not consider)
I BackTracking algorithm

6 / 47
BackTracking algorithm

Construct elements of the configuration step-by-step


Initialization: Constructed configuration is null: ()
Step 1:
I Compute (base on P) a set S1 of candidates for the first position of
the configuration under construction
I Select an item of S1 and put it in the first position

7 / 47
BackTracking algorithm

At Step k: Suppose we have partial configuration a1 , . . . , ak−1


Compute (base on P) a set Sk of candidates for the k th position of
the configuration under construction
I If Sk 6= ∅, then select an item of Sk and put it in the k th position and
obtain (a1 , . . . , ak−1 , ak )
F If k = n, then process the complete configuration a1 , . . . , an )
F Otherwise, construct the k + 1th element of the partial configuration in
the same schema
0
I If Sk = ∅, then backtrack for trying another item ak−1 for the k − 1th
position
0
F If ak−1 exists, then put it in the k − 1th position
F Otherwise, backtrack for trying another item for the k − 2th position, ...

8 / 47
BackTracking algorithm

Algorithm 1: TRY(k)
Construct a candidate set Sk ;
foreach y ∈ Sk do
ak ← y ;
if (a1 , . . . , ak ) is a complete configuration then
ProcessConfiguration(a1 , . . . , ak );
else
TRY(k + 1);

Algorithm 2: Main()
TRY(1);

9 / 47
BackTracking algorithm - binary sequence

A configuration is represented by b1 , b2 , . . . , bn
Candidates for bi is {0, 1}

10 / 47
BackTracking algorithm - binary sequence
1 public class ListingBinary {
2 private int [] a ;
3 private int n ;
4 private void TRY ( int i ){
5 for ( int v = 0; v <= 1; v ++){
6 a[i] = v;
7 if ( i == n -1){
8 for ( int j = 0; j < n ; j ++) System . out . print ( a [ j ]);
9 System . out . println ();
0 } else {
1 TRY ( i +1);
2 }
3 }
4 }
5 public void list ( int n ){
6 this . n = n ;
7 a = new int [ n ];
8 TRY (0);
9 }
0 public static void main ( String [] args ) {
1 ListingBinary LB = new ListingBinary ();
2 LB . list (4);
3 }
4
5 } 11 / 47
BackTracking algorithm - combination

A configuration is represented by (c1 , c2 , . . . , ck )


I dummy c0 = 1
I Candidates for ci being aware of hc1 , c2 , . . . , ci−1 i:
ci−1 + 1 ≤ ci ≤ n − k + i, ∀i = 1, 2, . . . , k

12 / 47
BackTracking algorithm - combination

Algorithm 3: TRY(i)
foreach v = ci−1 + 1, . . . , n − k + i do
ci ← v ;
if i == k then
printConfiguration();
else
TRY(i + 1);

Algorithm 4: MainCombinationGeneration(n, k)
c0 ← 0;
TRY(1);

13 / 47
BackTracking algorithm - permutation

A configuration: p1 , p2 , . . . , pk
Candidates for pi being aware of hp1 , p2 , . . . , pi−1 i:
{1, 2, . . . , n} \ {p1 , p2 , . . . , pi−1 }
Use an array of booleans for making values used b1 , b2 , . . . , bn
I bv = 1, if value v is already used (appear in p1 , p2 , . . . , pi−1 )
I bv = 0, otherwise

14 / 47
BackTracking algorithm - permutation
Algorithm 5: TRY(i)
foreach v = 1, . . . , n do
if visited[v ] = FALSE then
pi ← v ;
visited[v ] ← TRUE ;
if i == n then
printConfiguration();
else
TRY(i + 1);
visited[v ] ← FALSE ;

Algorithm 6: MainPermutationGeneration(n, k)
foreach v = 1, . . . , n do
visited[v ] ← FALSE ;
TRY(1);
15 / 47
BackTracking algorithm - Linear integer equation

Solve the linear equations in a set of positive integers

x1 + x2 + · · · + xn = M

where (ai )1≤i≤n and M are positive integers


Partial solution (x1 , x2 , . . . , xk−1 )
m = k−1
P
i=1 xi
A=n−k
M =M −m−A
Candidates of xk is {v ∈ Z | 1 ≤ v ≤ M}

16 / 47
BackTracking algorithm - Linear Integer Equation
Algorithm 7: TRY(i)
if i = n then
M ← M −f;
M ← M −f;
else
M ← M − f − (n − i);
M ← 1;
foreach v = M, . . . , M do
xi ← v ;
f ← f + v;
if i == n then
printConfiguration();
else
TRY(i + 1);
f ← f − v;

Algorithm 8: MainLinearEquation(n, M)
f ← 0;
TRY(1);

17 / 47
BackTracking algorithm - n-queens problem

Problem: Place n queens on a chess board such that no two queens


attack each other
Solution model: (x1 , x2 , . . . , xn ) where xi represents the row on which
the queen in column i is located
Constraints:
I xi 6= xj , ∀1 ≤ i < j ≤ n
I |xi − xj | =6 |i − j|, ∀1 ≤ i < j ≤ n

18 / 47
BackTracking algorithm - n-queens problem
Algorithm 9: Candidate(v , i)
foreach j = 1, . . . , i − 1 do
if xj = v ∨ |xj − v | = |j − i| then
return FALSE;
return TRUE;

Algorithm 10: TRY(i)


foreach v = 1, . . . , n do
if Candidate(v , i) then
xi ← v ;
if i == n then
Solution();
else
TRY(i + 1);

Algorithm 11: MainQueen(n)


TRY(1);

19 / 47
BackTracking algorithm - n-queens problem - refinement

Use arrays for marking forbidden cells


I r [1..n]: r [i] = false if the cells on row i are forbidden
I d1 [1 − n..n − 1]: d1 [q] = false if cells (r , c) s.t. c − r = q are forbiden
F in Java, indices of elements of an array cannot be negative (i.e., indices
are 0, 1, ...). Hence making a deplacement: d1 [q + n − 1] instead of
d1 [q]
I d2 [2..2n − 2]: d2 [q] =false if cells (r , c) s.t. r + c = q are forbiden

20 / 47
BackTracking algorithm - n-queens problem - refinement

Algorithm 12: TRY(i)


foreach v = 1, . . . , n do
if r [v ] ∧ d1 [i − v ] ∧ d2 [i + v ] then
xi ← v ;
r [v ] ← FALSE;
d1 [i − v ] ← FALSE;
d2 [i + v ] ← FALSE;
if i = n then
Solution();
else
TRY(i + 1);
r [v ] ← TRUE;
d1 [i − v ] ← TRUE;
d2 [i + v ] ← TRUE;

21 / 47
BackTracking algorithm - n-queens problem - refinement

Algorithm 13: MainQueenRefine(n)


foreach v = 1, . . . , n do
r [v ] ← TRUE;
foreach v = 1 − n, . . . , n − 1 do
d1 [v ] ← TRUE;
foreach v = 2, . . . , 2n do
d2 [v ] ← TRUE;
TRY(1);

22 / 47
Combinatorial Optimization Problems

z = min {f (x) : x ∈ X }
Applications
I Vehicle Routing
I Scheduling
I Timetabling
I Bin Packing
I Resource allocations
I ...

23 / 47
Generic schema of Branch and Bound

Branch-and-Bound splits the given problem into smaller and smaller


subproblems until they become easy to solve (Branching)
S
I X is splited into subsets X1 . . . , Xk (k ≥ 2) such that i=1,...,k Xi = X
I Recursive application of splitting defines a tree structure: search tree
(each node is a subset of X )
Normally, the size of the search tree is too large (exponential)
Bounding
I For each set Xi (∀i = 1, . . . , k)
F z i = min {f (x) : x ∈ Xi }
F compute z i and z i respectively the lower bound and upper bound of z i :
zi ≤ zi ≤ zi
I If there exist i 6= j s.t. z i ≤ z j , then the set Xj can be removed from
the search space since z j ≥ z i (no need to explore Xj )
I Suppose that z ∗ is incumbent (best solution found so far). If z i ≥ z ∗ ,
then Xi can be removed (no need to explore Xi since z ∗ ≤ z i ≤ z i )

24 / 47
Generic schema of Branch and Bound - example

25 / 47
Generic schema of Branch and Bound algorithms
(minimization problems)
Algorithm 14: TRY(k)
Construct a candidate set Sk ;
foreach y ∈ Sk do
ak ← y ;
if (a1 , . . . , ak ) is a complete configuration then
if f (a1 , . . . , ak ) < z ∗ then
z ∗ ← f (a1 , . . . , ak );
else
if z(a1 , . . . , ak ) < z ∗ then
TRY(k + 1);

Algorithm 15: Main()


z ∗ ← +∞;
TRY(1);
26 / 47
Traveling Salesman Problem
Given a list of n cities with pairwise distances
Find the shortest route that visits each city exactly once and returns
to the origin city
x = (x1 , . . . , xn ), route is x1 → x2 → · · · → xn → x1
f (x) = c(x1 , x2 ) + c(x2 , x3 ) + · · · + c(xn , x1 )
5
4 3
2
4 1
7
1 2
3
 
0 3 7 4
 
 3 0 1 2 
c = 

 7 1 0 5 

4 2 5 0
27 / 47
Traveling Salesman Problem - Simple Branch-and-Bound

A subproblem
I Correspond to a prefix of the solution: x1 , x2 , ..., xk
I Lower bound:
z(x1 , ..., xk ) = c(x1 , x2 ) + ... + c(xk−1 , xk ) + (n − k + 1) ∗ cmin where
cmin is the minimum element of the cost matrix (exclusive elements of
the diagonal)
I Recursive procedure extend(hx1 , ..., xk−1 i) will extend current partial
solution

28 / 47
Traveling Salesman Problem - Simple Branch-and-Bound
Algorithm 16: TRY(k)
Input: k: the index of k th city to be visited
n, c, x, f ∗ , f , visited are global variables
Output: Extend current partial solution x1 , . . . , xk−1 by assigning a value to xk
foreach v = 1, . . . , n do
if visited[v ] = FALSE then
xk ← v ;
visited[v ] ← TRUE ;
f ← f + c(xk−1 , xk );
if k = n then
if f + c(xn , x1 ) < f ∗ then
f ∗ ← f + c(xn , x1 );
else
z ← f + (n − k + 1) ∗ cmin;
if z < f ∗ then
TRY(k + 1);

f ← f − c(xk−1 , xk );
visited[v ] ← FALSE ;

29 / 47
Traveling Salesman Problem - Simple Branch-and-Bound

Algorithm 17: MainSimpleBBTSP(n, c)


Input: n, c: number of cities n and distance matrix c
x, f ∗ , f , visited are initialized as global variables
Output: The length of the shortest tour
foreach v = 1, . . . , n do
visited[v ] ← FALSE ;
f ∗ ← ∞;
f ← 0;
x1 ← 1;
visited[x1 ] ← TRUE ;
TRY(2);
return f ∗ ;

30 / 47
Traveling Salesman Problem - Second Branch-and-Bound

Lower bound
I A Tour is associated with a set S of n cells of the cost matrix in which
each row, column of the cost matrix contain exactly one element of S.
I Hence the optimal Tour does not change if we subtract each cell of a
given row (or column) with a same value.
I Algorithm reduce will compute the lower bound of the optimal tour

31 / 47
Traveling Salesman Problem

Algorithm 18: reduce(C)


1..k is the size of the cost matrix C ;
S ← 0;
foreach i ∈ 1..k do
minRow ← minimum value of row i of C ;
if minRow > 0 then
foreach j ∈ 1..k do
C [i][j] = C [i][j] − minRow ;
S ← S + minRow ;

foreach j ∈ 1..k do
minCol ← minimum value of column j of C ;
if minCol > 0 then
foreach i ∈ 1..k do
C [i][j] = C [i][j] − minCol;
S ← S + minCol;

return S;

32 / 47
Traveling Salesman Problem - Branching

Select an arc (u, v ) for branching (computed by bestEdge below)


I Tours contain (u, v )
F Remove row u and column v
F Set C [v ][u] = ∞
F If u is a terminating node of a path hx1 , x2 , ..., ui and v is a starting
node of a path hv , y1 , ..., yk i, then C [yk ][x1 ] = ∞ to prevent sub-tour
I Tours do not contain (u, v )
F Set C [u][v ] = ∞

33 / 47
Traveling Salesman Problem - Branching

When the reduced matrix has size 2 × 2

a. admit (u, w ) and (v , x) b. admit (u, x) and (v , w )

34 / 47
Traveling Salesman Problem - Branching

Algorithm 19: bestEdge(C)


1..k is the size of the cost matrix C ;
best ← −∞;
foreach i ∈ 1..k do
foreach j ∈ 1..k do
if C [i][j] = 0 then
minRow ← smallest element of row i which is different from C [i][j];
minCol ← smallest element of column j which is different from C [i][j];
total ← minRow + minCol;
if total > best then
best ← total;
selRow ← i;
selCol ← j;

return (selRow , selCol)

35 / 47
Traveling Salesman Problem

a. Original Cost matrix b. Reduced matrix

36 / 47
Traveling Salesman Problem

Set of Tours is divided into 2 cases:

37 / 47
Traveling Salesman Problem

Set of Tours containing (6,3) is divided into 2 cases:

38 / 47
Traveling Salesman Problem

Set of Tours containing (6,3), (4,6) is divided into 2 cases:

39 / 47
Traveling Salesman Problem

Set of Tours containing (6,3), (4,6), (2,1) is divided into 2 cases:

40 / 47
Traveling Salesman Problem

Set of Tours containing (6,3), (4,6), not (2,1) is divided into 2 cases:

41 / 47
Traveling Salesman Problem

Set of Tours containing (6,3), (4,6), (5,1), not (2,1)


is divided into 2 cases:

Finally, the best Tour has cost 104

42 / 47
Branch-and-Bound: MaxClique
Description
I Input: undirected graph G = (V , E ),
I Subgraph: Let G (S) be the graph (S, ES ) in which
ES = {(u, v ) | u, v ∈ S ∧ (u, v ) ∈ E }. G (S) is called subgraph induced
by S (∀S ⊆ V )
I Output: maximal complete subgraph (or clique) of G
Branch-and-Bound
I Partial solution Q: set of nodes, two nodes of Q are adjacent
I Candidate nodes Cand for expansion: each node of Cand is adjacent
with all nodes of Q
I Upper Bound
F ∆ is the number of colors used to color nodes of Cand such that two
adjacent nodes u, v ∈ Cand must be colored by different colors.
F The size of every complete subgraph of G (Cand) is less than or equal
to ∆
F |Q| + ∆ is the upper bound of the size of cliques expanded from Q
F If |Q| + ∆ ≤ |Qmax|, then do not expand Q

43 / 47
Branch-and-Bound: MaxClique

Algorithm 20: MaxClique(G = (V , E ))


Input: Graph G = (V , E )
Output: Maximal complete subgraph of G
Qmax ← {};
Q ← {};
Cand ← list of nodes of V ;
∆ ← Sort(Cand);
Expand(Cand);
return Qmax;

44 / 47
Branch-and-Bound: MaxClique

Algorithm 21: Expand(Cand)


Input: Sorted List of candidates Cand, G = (V , E ) and Q, Qmax are global variables
Output: Expanding the partial solution Q
foreach i = 0, . . . , lenght(Cand) − 1 do
u ← Cand[i];
Q ← Q ∪ {u};
if |Q| > |Qmax| then
Qmax ← Q;
Cand 0 ← {v ∈ Cand | v 6= u ∧ (u, v ) ∈ E };
∆ ← Sort(Cand 0 );
if |Q| + ∆ > |Qmax| then
Expand(Cand 0 );
Q ← Q \ {u};

45 / 47
Branch-and-Bound: MaxClique
Algorithm 22: Sort(Cand)
Input: Sort the List of candidates Cand
Output: Updated Cand and return the number classes
maxNo ← 0;
C1 ← {};
foreach u ∈ Cand do
k ← 1;
while ∃v ∈ Ck | (u, v ) ∈ E do
k ← k + 1;
if k > maxNo then
maxNo ← k;
Ck ← {};
Ck ← Ck ∪ {u}
L ← [];
foreach k = 1, . . . , maxNo do
foreach v ∈ Ck do
L ← L :: v ;

foreach i = 0, . . . , length(L) − 1 do
Cand[i] ← L[length(L) − i − 1];
return maxNo;

46 / 47
Exercises

Nurses Scheduling
Balanced Courses Assignment
Packing 2D rectangle items into the container
MaxClique
Networks analysis (count number of k-paths on a graph, a tree)

47 / 47

You might also like