DAA - Backtracking Branch and Bound
DAA - Backtracking Branch and Bound
LECTURE NOTES
UNIT–IV
Backtracking:
Backtracking is one of the techniques that can be used to solve the problem. We can write the algorithm using
this strategy. It uses the Brute force search to solve the problem, and the brute force search says that for the
given problem, we try to make all the possible solutions and pick out the best solution from all the desired
solutions. This rule is also followed in dynamic programming, but dynamic programming is used for solving
optimization problems. In contrast, backtracking is not used in solving optimization problems. Backtracking is
used when we have multiple solutions, and we require all those solutions.
Backtracking name itself suggests that we are going back and coming forward; if it satisfies the condition, then
return success, else we go back again. It is used to solve a problem in which a sequence of objects is chosen
from a specified set so that the sequence satisfies some criteria. When we have multiple choices, then we make
the decisions from the available choices. In the following cases, we need to use the backtracking algorithm:
A piece of sufficient information is not available to make the best choice, so we use the backtracking strategy to
try out all the possible solutions. Each decision leads to a new set of choices. Then again, we backtrack to make
new decisions. In this case, we need to use the backtracking strategy.
Backtracking is a systematic method of trying out various sequences of decisions until you find out that works.
Let's understand through an example.
We start with a start node. First, we move to node A. Since it is not a feasible solution so we move to the next
node, i.e., B. B is also not a feasible solution, and it is a dead-end so we backtrack from node B to node A.
Suppose another path exists from node A to node C. So, we move from node A to node C. It is also a
dead-end, so again backtrack from node C to node A. We move from node A to the starting node.
1
Now we will check any other path exists from the starting node. So, we move from start node to the
node D. Since it is not a feasible solution so we move from node D to node E. The node E is also not a
feasible solution. It is a dead end so we backtrack from node E to node D.
Suppose another path exists from node D to node F. So, we move from node D to node F. Since it is not
a feasible solution and it's a dead-end, we check for another path from node F.
Suppose there is another path exists from the node F to node G so move from node F to node G. The
node G is a success node.
2
The terms related to the backtracking are:
Live node: The nodes that can be further generated are known as live nodes.
E node: The nodes whose children are being generated and become a success node.
Success node: The node is said to be a success node if it provides a feasible solution.
Dead node: The node which cannot be further generated and also does not provide a feasible solution is
known as a dead node.
Many problems can be solved by backtracking strategy, and that problems satisfy complex set of constraints,
and these constraints are of two types:
Implicit constraint: It is a rule in which how each element in a tuple is related.
Explicit constraint: The rules that restrict each element to be chosen from the given set.
Applications of Backtracking
N-queen problem
Sum of subset problem
Graph coloring
Hamiliton cycle
N-Queens Problem:
N - Queens problem is to place n - queens in such a manner on an n x n chessboard that no queens attack each
other by being in the same row, column or diagonal.
It can be seen that for n =1, the problem has a trivial solution, and no solution exists for n =2 and n =3. So first
we will consider the 4 queens problem and then generate it to n - queen’s problem.
Given a 4 x 4 chessboard and number the rows and column of the chessboard 1 through 4.
Since, we have to place 4 queens such as q1 q2 q3 and q4 on the chessboard, such that no two queens attack
each other. In such a conditional each queen must be placed on a different row, i.e., we put queen "i" on
row "i."
Now, we place queen q1 in the very first acceptable position (1, 1). Next, we put queen q2 so that both these
queens do not attack each other. We find that if we place q2 in column 1 and 2, then the dead end is
encountered. Thus the first acceptable position for q2 in column 3, i.e. (2, 3) but then no position is left for
placing queen 'q3' safely. So we backtrack one step and place the queen 'q2' in (2, 4), the next best possible
solution. Then we obtain the position for placing 'q3' which is (3, 2). But later this position also leads to a dead
end, and no place is found where 'q4' can be placed safely. Then we have to backtrack till 'q1' and place it to (1,
2) and then all other queens are placed safely by moving q2 to (2, 4), q3 to (3, 1) and q4 to (4, 3). That is, we get
the solution (2, 4, 1, 3). This is one possible solution for the 4-queens problem. For another possible solution,
the whole method is repeated for all partial solutions. The other solutions for 4 - queens problems is (3, 1, 4, 2)
i.e.
3
The implicit tree for 4 - queen problem for a solution (2, 4, 1, 3) is as follows:
4
4 - Queens solution space with nodes numbered in DFS
It can be seen that all the solutions to the 4 queens problem can be represented as 4 - tuples (x1, x2, x3, x4)
where xi represents the column on which queen "qi" is placed.
One possible solution for 8 queens problem is shown in fig:
Program:
#include<stdio.h>
#include<math.h>
int board[20],count;
int main()
{
int n,i,j;
void queen(int row,int n);
5
{
int i,j;
printf("\n\nSolution %d:\n\n",++count);
for(i=1;i<=n;++i)
printf("\t%d",i);
for(i=1;i<=n;++i)
{
printf("\n\n%d",i);
for(j=1;j<=n;++j) //for nxn board
{
if(board[i]==j)
printf("\tQ"); //queen at i,j position
else
printf("\t-"); //empty slot
}
}
}
/*funtion to check conflicts
If no conflict for desired postion returns 1 otherwise returns 0*/
int place(int row,int column)
{
int i;
for(i=1;i<=row-1;++i)
{
//checking column and digonal conflicts
if(board[i]==column)
return 0;
else
if(abs(board[i]-column)==abs(i-row))
return 0;
}
return 1; //no conflicts
}
//function to check for proper positioning of queen
void queen(int row,int n)
{
int column;
for(column=1;column<=n;++column)
{
if(place(row,column))
{
board[row]=column; //no conflicts so place queen
if(row==n) //dead end
print(n); //printing the board configuration
else //try queen with next position
queen(row+1,n);
}
}
}
6
Graph Coloring Problem:
Graph coloring refers to the problem of coloring vertices of a graph in such a way that no two adjacent vertices
have the same color. This is also called the vertex coloring problem.
If coloring is done using at most k colors, it is called k-coloring.
The smallest number of colors required for coloring graph is called its chromatic number.
The chromatic number is denoted by X(G). Finding the chromatic number for the graph is NP-complete
problem.
Graph coloring problem is both, decision problem as well as an optimization problem. A decision
problem is stated as, “With given M colors and graph G, whether such color scheme is possible or
not?”.
The optimization problem is stated as, “Given M colors and graph G, find the minimum number of
colors required for graph coloring.”
Graph coloring problem is a very interesting problem of graph theory and it has many diverse
applications. Few of them are listed below.
Applications of Graph Coloring Problem
Design a timetable.
Sudoku
Register allocation in the compiler
Map coloring
Mobile radio frequency assignment:
The input to the graph is an adjacency matrix representation of the graph. Value M(i, j) = 1 in the
matrix represents there exists an edge between vertex i and j. A graph and its adjacency matrix
representation are shown in Figure (a)
7
The problem can be solved simply by assigning a unique color to each vertex, but this solution is not optimal. It
may be possible to color the graph with colors less than |V|. Figure (b) and figure (c) demonstrate both such
instances. Let Ci denote the ith color.
If we assign color 1 to vertex A, the same color cannot be assigned to vertex B or C. In the next step, B is
assigned some different colors 2. Vertex A is already colored and vertex D is a neighbor of B, so D cannot be
assigned color 2. The process goes on. State-space tree is shown in Figure (e)
8
Thus, vertices A and C will be colored with color 1, and vertices B and D will be colored with color 2.
Complexity Analysis
The number of anode increases exponentially at every level in state space tree. With M colors and n vertices,
total number of nodes in state space tree would be
1 + M + M2 + M3 + …. + Mn
Examples on Graph Coloring Problem
Example: Apply backtrack on the following instance of graph coloring problem of 4 nodes and 3 colors
This problem can be solved using backtracking algorithms. The formal idea is to list down all the vertices and
colors in two lists. Assign color 1 to vertex 1. If vertex 2 is not adjacent to vertex 1 then assign the same color,
otherwise assign color 2. The process is repeated until all vertices are colored. The algorithm backtracks
whenever color i is not possible to assign to any vertex k and it selects the next color i + 1 and the test is
repeated. This graph can be colored with 3 colors.
The solution tree is shown in Fig. (i):
9
Vertex Assigned Color
1 c1
2 c2
3 c3
4 c1
Program:
#include<stdio.h>
static int m, n;
static int c=0;
static int count=0;
int g[50][50];
int x[50];
void nextValue(int k);
void GraphColoring(int k);
void main()
{
int i, j;
int temp;
printf("\nEnter the number of nodes: " );
scanf("%d", &n);
/*
printf("\nIf edge exists then enter 1 else enter 0 \n");
for(i=1; i<=n; i++)
{
x[i]=0;
for(j=1; j<=n; j++)
10
{
if(i==j)
g[i][j]=0;
else
{
printf("%d -> %d: " , i, j);
scanf("%d", &temp);
g[i][j]=g[j][i]=temp;
}
}
}
*/
printf("\nEnter Adjacency Matrix:\n");
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d", &g[i][j]);
}
}
printf("\nPossible Solutions are\n");
for(m=1;m<=n;m++)
{
if(c==1)
{
break;
}
GraphColoring(1);
}
printf("\nThe chromatic number is %d", m-1);
//in for loop, m gets incremented first and then the condition is checked
//so it is m minus 1
printf("\nThe total number of solutions is %d", count);
}
void GraphColoring(int k)
{
int i;
while(1)
{
nextValue(k);
if(x[k]==0)
{
return;
}
if(k==n)
{
c=1;
for(i=1;i<=n;i++)
{
printf("%d ", x[i]);
11
}
count++;
printf("\n");
}
else
GraphColoring(k+1);
}
}
void nextValue(int k)
{
int j;
while(1)
{
x[k]=(x[k]+1)%(m+1);
if(x[k]==0)
{
return;
}
for(j=1;j<=n;j++)
{
if(g[k][j]==1&&x[k]==x[j])
break;
}
if(j==(n+1))
{
return;
}
}
}
Hamiltonian Cycle using Backtracking:
The Hamiltonian cycle is the cycle in the graph which visits all the vertices in graph exactly once and terminates
at the starting node. It may not include all the edges
The Hamiltonian cycle problem is the problem of finding a Hamiltonian cycle in a graph if there exists any such
cycle.
The input to the problem is an undirected, connected graph. For the graph shown in Figure (a), a path A – B – E
– D – C – A forms a Hamiltonian cycle. It visits all the vertices exactly once, but does not visit the edges <B, D>.
The Hamiltonian cycle problem is also both, decision problem and an optimization problem. A decision problem
is stated as, “Given a path, is it a Hamiltonian cycle of the graph?”.
The optimization problem is stated as, “Given graph G, find the Hamiltonian cycle for the graph.”
12
We can define the constraint for the Hamiltonian cycle problem as follows:
In any path, vertex i and (i + 1) must be adjacent.
1st and (n – 1)th vertex must be adjacent (nth of cycle is the initial vertex itself).
Vertex i must not appear in the first (i – 1) vertices of any path.
With the adjacency matrix representation of the graph, the adjacency of two vertices can be verified in
constant time.
Complexity Analysis
Looking at the state space graph, in worst case, total number of nodes in tree would be,
T(n) = 1 + (n – 1) + (n – 1)2 + (n – 1)3 + … + (n – 1)n – 1
T(n) = O(nn). Thus, the Hamiltonian cycle algorithm runs in exponential time.
Example: Show that given graph has a Hamiltonian cycle
Solution:
We can start with any random vertex. Let us start with vertex A. Neighbors of A are {B, C, D}. The inclusion of B
does not lead to a complete solution. So explore it as shown in Figure (c).
Adjacent vertices to B are {C, D}. The inclusion of C does not lead to a complete solution. All adjacent vertices of
C are already members of the path formed so far. So it leads to a dead end.
Backtrack and go to B and explore its next neighbor i.e. D.
The inclusion of D does not lead to a complete solution, and all adjacent vertices of D are already a member of
the path formed so far. So it leads to a dead end.
Backtrack and go to B. Now B does not have any more neighbors, so backtrack and go to A. Explore the next
neighbor of A i.e. C. By repeating the same procedure, we get the state space trees as shown below. And path
A – C – B – D – A is detected as the Hamiltonian cycle of the input graph
13
Explain how to find Hamiltonian Cycle by using Backtracking in a given graph
Solution:
The backtracking approach uses a state-space tree to check if there exists a Hamiltonian cycle in the graph.
Figure (f) shows the simulation of the Hamiltonian cycle algorithm. For simplicity, we have not explored all
possible paths, the concept is self-explanatory.
Step 1: Tour is started from vertex 1. There is no path from 5 to 1. So it’s the dead-end state.
Step 2: Backtrack to the node from where the new path can be explored, that is 3 here
14
Step 3: New path also leads to a dead end so backtrack and explore all possible paths
Step 4: Next path is also leading to a dead-end so keep backtracking until we get some node that can
generate a new path, i.e .vertex 2 here
15
Step 5: One path leads to Hamiltonian cycle, next leads to a dead end so backtrack and explore all possible
paths at each vertex
16
Branch and bound:
Branch and bound is one of the techniques used for problem solving. It is similar to the backtracking since it
also uses the state space tree. It is used for solving the optimization problems and minimization problems. If we
have given a maximization problem then we can convert it using the Branch and bound technique by simply
converting the problem into a maximization problem.
Jobs = {j1, j2, j3, j4}
P = {10, 5, 8, 3}
d = {1, 2, 1, 2}
The above are jobs, problems and problems given. We can write the solutions in two ways which are given
below:
Suppose we want to perform the jobs j1 and j2 then the solution can be represented in two ways:
The first way of representing the solutions is the subsets of jobs.
S1 = {j1, j4}
The second way of representing the solution is that first job is done, second and third jobs are not done, and
fourth job is done.
S2 = {1, 0, 0, 1}
The solution s1 is the variable-size solution while the solution s2 is the fixed-size solution.
First, we will see the subset method where we will see the variable size.
First method:
In this case, we first consider the first job, then second job, then third job and finally we consider the last job.
17
As we can observe in the above figure that the breadth first search is performed but not the depth first search.
Here we move breadth wise for exploring the solutions. In backtracking, we go depth-wise whereas in branch
and bound, we go breadth wise.
Now one level is completed. Once I take first job, then we can consider either j2, j3 or j4. If we follow the route
then it says that we are doing jobs j1 and j4 so we will not consider jobs j2 and j3.
Now we will consider the node 3. In this case, we are doing job j2 so we can consider either job j3 or j4. Here,
we have discarded the job j1.
Now we will expand the node 4. Since here we are doing job j3 so we will consider only job j4.
Now we will expand node 6, and here we will consider the jobs j3 and j4.
18
Now we will expand node 7 and here we will consider job j4.
Now we will expand node 9, and here we will consider job j4.
The last node, i.e., node 12 which is left to be expanded. Here, we consider job j4.
19
The above is the state space tree for the solution s1 = {j1, j4}
Second method:
We will see another way to solve the problem to achieve the solution s1.
First, we consider the node 1 shown as below:
Now, we will expand the node 1. After expansion, the state space tree would be appeared as:
On each expansion, the node will be pushed into the stack shown as below:
Now the expansion would be based on the node that appears on the top of the stack. Since the node 5 appears
on the top of the stack, so we will expand the node 5. We will pop out the node 5 from the stack. Since the
node 5 is in the last job, i.e., j4 so there is no further scope of expansion.
The next node that appears on the top of the stack is node 4. Pop out the node 4 and expand. On expansion,
job j4 will be considered and node 6 will be added into the stack shown as below:
20
The next node is 6 which is to be expanded. Pop out the node 6 and expand. Since the node 6 is in the last job,
i.e., j4 so there is no further scope of expansion.
The next node to be expanded is node 3. Since the node 3 works on the job j2 so node 3 will be expanded to
two nodes, i.e., 7 and 8 working on jobs 3 and 4 respectively. The nodes 7 and 8 will be pushed into the stack
shown as below:
21
The next node that appears on the top of the stack is node 8. Pop out the node 8 and expand. Since the node 8
works on the job j4 so there is no further scope for the expansion.
The next node that appears on the top of the stack is node 7. Pop out the node 7 and expand. Since the node 7
works on the job j3 so node 7 will be further expanded to node 9 that works on the job j4 as shown as below
and the node 9 will be pushed into the stack.
The next node that appears on the top of the stack is node 9. Since the node 9 works on the job 4 so there is no
further scope for the expansion.
The next node that appears on the top of the stack is node 2. Since the node 2 works on the job j1 so it means
that the node 2 can be further expanded. It can be expanded upto three nodes named as 10, 11, 12 working on
jobs j2, j3, and j4 respectively.
There newly nodes will be pushed into the stack shown as below:
22
In the above method, we explored all the nodes using the stack that follows the LIFO principle.
Third method:
There is one more method that can be used to find the solution and that method is Least cost branch and
bound. In this technique, nodes are explored based on the cost of the node. The cost of the node can be
defined using the problem and with the help of the given problem, we can define the cost function. Once the
cost function is defined, we can define the cost of the node.
Let's first consider the node 1 having cost infinity shown as below:
Now we will expand the node 1. The node 1 will be expanded into four nodes named as 2, 3, 4 and 5 shown as
below:
Let's assume that cost of the nodes 2, 3, 4, and 5 are 25, 12, 19 and 30 respectively.
Since it is the least cost branch n bound, so we will explore the node which is having the least cost. In the above
figure, we can observe that the node with a minimum cost is node 3. So, we will explore the node 3 having cost
12.
Since the node 3 works on the job j2 so it will be expanded into two nodes named as 6 and 7 shown as below:
23
The node 6 works on job j3 while the node 7 works on job j4. The cost of the node 6 is 8 and the cost of the
node 7 is 7. Now we have to select the node which is having the minimum cost. The node 7 has the minimum
cost so we will explore the node 7. Since the node 7 already works on the job j4 so there is no further scope for
the expansion.
FIFO Branch and Bound solution
FIFO Branch and Bound solution is one of the methods of branch and bound.
Branch and Bound is the state space search method where all the children E-node that is generated before the
live node, becomes an E- node.
FIFO branch and bound search is the one that follows the BFS like method. It does so as the list follows first in
and first out.
Some key terms to keep in mind while proceeding further:
What is a live node?
A live node is the one that has been generated but its children are not yet generated.
What is an E node?
An E node is the one that is being explored at the moment.
What is a dead node?
A dead node is one that is not being generated or explored any further. The children of the dead node have
already been expanded to their full capacity.
To proceed further with the FIFO branch and bound we use a queue.
To begin with, we keep the queue empty. Then we assume a node 1.
In FIFO search the E node is assumed as node 1. After that, we need to generate children of Node 1. The
children are the live nodes, and we place them in the queue accordingly. Then we delete node 2 from the
queue and generate children of node 2.
Next, we delete another element from the queue and assume that as the E node. We then generate all its
children.
In the same process, we delete the next element and generate their children. We keep repeating the process
till the queue is covered and we find a node that satisfies the conditions of the problem. When we have found
the answer node, the process terminates.
Let us understand it through an example:
24
In the given diagram we have assumed that node 12 is the answer node.
As mentioned we start by assuming node 1 as the E node and generate all its children.
2 3 4
Then we delete node 1 from the queue, take node 2 as the E node, and generate all its children:
3 4 5 6
We delete the next element and generate children for the next node, assuming it to be the E node.
4 5 6
We repeat the same process. The generated children of 4, that is node 9 are killed by the boundary
function.
5 6
Similarly, we proceed further, but the children of nodes 5, meaning the nodes 10, and 11 are also generated
and killed by boundary function. The last standing node in the queue is 6, the children of node 6 are 12, and it
satisfies all the conditions for the problem, therefore it is the answer node.
Least Cost (LC) Search:
The selection rule for the next E-node in FIFO or LIFO branch and bound is sometimes
“blind”. i.e., the selection rule does not give any preference to a node that has a very good
chance of getting the search to an answer node quickly.
The search for an answer node can often be speeded by using an “intelligent” ranking
function. It is also called an approximate cost function “Ĉ”.
Expended node (E-node) is the live node with the best Ĉ value.
Branching: A set of solutions, which is represented by a node, can be partitioned into
mutually (jointly or commonly) exclusive (special) sets. Each subset in the partition is
represented by a child of the original node.
Lower bounding: An algorithm is available for calculating a lower bound on the cost of any
solution in a given subset.
Each node X in the search tree is associated with a cost: Ĉ(X)
C=cost of reaching the current node, X(E-node) form the root + The cost of reaching an
answer node form X.
Ĉ=g(X)+H(X).
Example:
8-puzzle
Cost function: Ĉ = g(x) +h(x)
where h(x) = the number of misplaced tiles
and g(x) = the number of moves so far
Assumption: move one tile in any direction cost 1.
25
Traveling Salesperson problem using branch and bound:
Given the vertices, the problem here is that we have to travel each vertex exactly once and reach back to the
starting point. Consider the below graph:
26
As we can observe in the above graph that there are 5 vertices given in the graph. We have to find the shortest
path that goes through all the vertices once and returns back to the starting vertex. We mainly consider the
starting vertex as 1, then traverse through the vertices 2, 3, 4, and 5, and finally return to vertex 1.
The adjacent matrix of the problem is given below:
Now we look at how this problem can be solved using the branch n bound.
Let's first understand the approach then we solve the above problem.
The graph is given below, which has four vertices:
Suppose we start travelling from vertex 1 and return back to vertex 1. There are various ways to travel through
all the vertices and returns to vertex 1. We require some tools that can be used to minimize the overall cost. To
solve this problem, we make a state space tree. From the starting vertex 1, we can go to either vertices 2, 3, or
4, as shown in the below diagram.
27
From vertex 2, we can go either to vertex 3 or 4. If we consider vertex 3, we move to the remaining vertex, i.e.,
4. If we consider the vertex 4 shown in the below diagram:
From vertex 3, we can go to the remaining vertices, i.e., 2 or 4. If we consider the vertex 2, then we move to
remaining vertex 4, and if we consider the vertex 4 then we move to the remaining vertex, i.e., 3 shown in the
below diagram:
From vertex 4, we can go to the remaining vertices, i.e., 2 or 3. If we consider vertex 2, then we move to the
remaining vertex, i.e., 3, and if we consider the vertex 3, then we move to the remaining vertex, i.e., 2 shown in
the below diagram:
28
The above is the complete state space tree. The state space tree shows all the possibilities. Backtracking and
branch n bound both use the state space tree, but their approach to solve the problem is different. Branch n
bound is a better approach than backtracking as it is more efficient. In order to solve the problem using branch
n bound, we use a level order. First, we will observe in which order, the nodes are generated. While creating
the node, we will calculate the cost of the node simultaneously. If we find the cost of any node greater than the
upper bound, we will remove that node. So, in this case, we will generate only useful nodes but not all the
nodes.
Let's consider the above problem.:
As we can observe in the above adjacent matrix that 10 is the minimum value in the first row, 2 is the minimum
value in the second row, 2 is the minimum value in the third row, 3 is the minimum value in the third row, 3 is
the minimum value in the fourth row, and 4 is the minimum value in the fifth row.
29
Now, we will reduce the matrix. We will subtract the minimum value with all the elements of a row. First, we
evaluate the first row. Let's assume two variables, i.e., i and j, where 'i' represents the rows, and 'j' represents
the columns.
When i = 0, j =0
M[0][0] = ∞-10= ∞
When i = 0, j = 1
M[0][1] = 20 - 10 = 10
When i = 0, j = 2
M[0][2] = 30 - 10 = 20
When i = 0, j = 3
M[0][3] = 10 - 10 = 0
When i = 0, j = 4
M[0][4] = 11 - 10 = 1
The matrix is shown below after the evaluation of the first row:
30
Consider the third row:
When i = 2, j =0
M[2][0] = 3-2= 1
When i = 2, j = 1
M[2][1] = 5 - 2= 3
When i = 2, j = 2
M[2][2] = ∞ - 2 = ∞
When i = 2, j = 3
M[2][3] = 2 - 2 = 0
When i = 2, j = 4
M[2][4] = 4 - 2 = 2
The matrix is shown below after the evaluation of the third row:
Consider the fourth row:
When i = 3, j =0
M[3][0] = 19-3= 16
When i = 3, j = 1
M[3][1] = 6 - 3= 3
When i = 3, j = 2
M[3][2] = 18 - 3 = 15
When i = 3, j = 3
M[3][3] = ∞ - 3 = ∞
When i = 3, j = 4
M[3][4] = 3 - 3 = 0
The matrix is shown below after the evaluation of the fourth row:
31
Consider the fifth row:
When i = 4, j =0
M[4][0] = 16-4= 12
When i = 4, j = 1
M[4][1] = 4 - 4= 0
When i = 4, j = 2
M[4][2] = 7 - 4 = 3
When i = 4, j = 3
M[4][3] = 16 - 4 = 12
When i = 4, j = 4
M[4][4] = ∞ - 4 = ∞
The matrix is shown below after the evaluation of the fifth row:
The above matrix is the reduced matrix with respect to the rows.
Now we reduce the matrix with respect to the columns. Before reducing the matrix, we first find the minimum
value of all the columns. The minimum value of first column is 1, the minimum value of the second column is 0,
the minimum value of the third column is 3, the minimum value of the fourth column is 0, and the minimum
value of the fifth column is 0, as shown in the below matrix:
Now we reduce the matrix.
Consider the first column.
When i = 0, j =0
M[0][0] = ∞-1= ∞
When i = 1, j = 0
M[1][0] = 13 - 1= 12
When i = 2, j = 0
M[2][0] = 1 - 1 = 0
When i = 3, j = 0
M[3][0] = 16 - 1 = 15
When i = 4, j = 0
M[4][0] = 12 - 1 = 11
The matrix is shown below after the evaluation of the first column:
32
Since the minimum value of the first and the third columns is non-zero, we will evaluate only first and third
columns. We have evaluated the first column. Now we will evaluate the third column.
Consider the third column.
When i = 0, j =2
M[0][2] = 20-3= 17
When i = 1, j = 2
M[1][2] = 13 - 1= 12
When i = 2, j = 2
M[2][2] = 1 - 1 = 0
When i = 3, j = 2
M[3][2] = 16 - 1 = 15
When i = 4, j = 2
M[4][2] = 12 - 1 = 11
The matrix is shown below after the evaluation of the third column:
The above is the reduced matrix. The minimum value of rows is 21, and the columns is 4. Therefore, the total
minimum value is (21 + 4) equals to 25.
Let's understand that how to solve this problem using branch and bound with the help of a state-space tree.
To make a state-space tree, first, we consider node 1. From node 1, we can go either to nodes 2, 3, 4, or 5 as
shown in the below image. The cost of node 1 would be the cost which we achieved in the above-reduced
matrix, i.e.., 25. Here, we will also maintain the upper bound. Initially, the upper bound would-be infinity.
33
Now, consider node 2. It means that we are moving from node 1 to node 2. Make the first row and second
column as infinity shown in the below matrix:
Once we move from node 1 to node 2, we cannot move back to node 1. Therefore, we have to make 2 to 1 as
infinity shown in the below matrix:
Since each row and column contains at least one zero value; therefore, we can say that above matrix has been
reduced. The cost of reduction of node 2 is c(1, 2) + r + r` = 10 + 25 + 0 = 35.
Now we will find the minimum value of each column of the new reduced matrix. The minimum value of the first
column is 11 and the minimum value of other three columns is 0.
Now, consider the node 3. It means that we are moving from the node 1 to node 3. Make the first row and
third column as infinity shown in the below matrix:
Once we move from the node 1 to node 3, we cannot move back to the node 1. Therefore, we have to
make 3 to 1 as infinity shown in the below matrix:
34
Since each row and column contains atleast one zero value; therefore, we can say that above matrix has been
reduced. The cost of reduction of node 3 is c(1, 3) + r + r` = 17 + 25 + 11= 53.
Now, consider the node 4. It means that we are moving from the node 1 to node 4. Make the first row and
forth column as infinity shown in the below matrix:
Once we move from the node 1 to node 4, we cannot move back to the node 1. Therefore, we have to make 4
to 1 as infinity shown in the below matrix:
Since each row and column contains atleast one zero value; therefore, we can say that above matrix has been
reduced. The cost of reduction of node 4 is c(1, 4) + r + r` = 0 + 25 + 0 = 25.
Now, consider the node 5. It means that we are moving from the node 1 to node 5. Make the first row and fifth
column as infinity shown in the below matrix:
Once we move from the node 1 to node 5, we cannot move back to the node 1. Therefore, we have to make 5
to 1 as infinity shown in the below matrix:
Since each row and column contains atleast one zero value; therefore, we can say that above matrix has been
reduced. In this case, second and third rows are non-zero. Therefore, we have to first find the minimum values
of both the rows. The minimum value of second row is 2; therefore, we subtract 2 from all the elements of the
second row. The elements of second row would be:
A[1][0] = 12-2 = 10
A[1][1] = ∞
A[1][2] = 11 - 2 = 9
A[1][3] = 2 - 2 = 0
A[1][4] = ∞ - 2 = ∞
As we can observe now that the second row contains one zero value.
The cost of reduction of node 5 is c(1, 5) + r + r` = 1 + 25 + 5 = 31
Since the node 4 has the minimum cost, i.e., 25. So we will explore the node 4 first. From the vertex 4, we can
go either to the vertex 2, 3 or 5 as shown in the below image:
Now we have to calculate the cost of the path from the vertex 4 to 2, vertex 4 to 3, and vertex 4 to 5. Here, we
will use the matrix of node 4 to find the cost of all the nodes.
First, we consider the path from the vertex 4 to the vertex 2. We make fourth row as ∞ and second column as
∞. Since we cannot move back from 2 to 1, so 1 to 2 is also infinity as shown in the below matrix:
Since all the rows and columns have atleast one zero value. Therefore, we can say that this matrix is already
reduced. So, there would be no reduction cost. The cost of reduction of node 2 is c(4, 2) + r + r` = 3 + 25 + 0 = 28
35
Now we have to calculate the cost of the path from the vertex 4 to the vertex 3. We make fourth row and third
column as infinity as shown in the below matrix. Since we cannot move from the vertex 3 to 1, so we make 3 to
1 as infinity shown in the below matrix:
Now we will check whether each row and column contain atleast one zero value or not. First, we observe all
the rows. Since the third row does not have a zero value, so we first find the minimum value of the third row.
The minimum value of the third row is 2, so we subtract 2 from all the elements of the third row. The elements
of third row would be:
A[2][0] = ∞ - 2 = ∞
A[2][1] = 3 - 2 = 1
A[2][2] = ∞ - 2 = ∞
A[2][3] = ∞ - 2 = ∞
A[2][4] = 2 - 2 = 0
As we can observe now that the third row contains one zero value.
The first column does not contain the zero value. The minimum value of the first column is 11. We subtract 11
from all the elements of the first column. The elements of first column would be:
A[0][0] = ∞ - 11 = ∞
A[1][0] = 12 - 11 = 1
A[2][0] = ∞ - 11= ∞
A[3][0] = ∞ - 11= ∞
A[4][0] = 11 - 11 = 0
As we can observe now that the first column contains one zero value. The total minimum cost is 11 +2 equals to
13. The cost of reduction of node 3 is c(4, 3) + r + r` = 12 + 25 + 13 = 50.
Now we will calculate the cost of the path from the vertex 4 to 5. We make fourth row and fifth column as
infinity. Since we cannot move back from the node 5 to 1, so we also make 1 to 5 as infinity shown in the below
matrix:
Now we will check whether each row and column contain atleast one zero value or not. First, we observe all
the rows. The second row does not contain the zero value, so we find the minimum value of the second row.
The minimum value is 11 so we subtract 11 from all the elements of the second row. The elements of second
row would be:
A[1][0] = 12 - 11 = 1
A[1][1] = ∞ - 11 = ∞
A[1][2] = 11 - 11 = 0
A[1][3] = ∞ - 11 = ∞
A[1][4] = ∞ - 11 = ∞
As we can observe now that the second row contains one zero value. The cost of reduction of node 5 is c(4, 5) +
r + r` = 0 + 25 + 11 = 36.
Now we will compare the cost of all the leaf nodes. The node with a cost 28 is minimum so we will explore this
node. The node with a cost 28 can be further expanded to the nodes 3 and 5 as shown in the below figure:
Now we have to calculate the cost of both the nodes, i.e., 3 and 5. First we consider the path from node 2 to
node 3. Consider the matrix of node 2 which is shown below:
We make second row and third column as infinity. Also, we cannot move back from the node 3 to node 1 so we
make 3 to 1 as infinity as shown in the below matrix:
36
Now we will check whether any row contains zero value or not. Since third row does not contain any zero value
so we will find the minimum value of the third row. The minimum value of the third row is 2 so we subtract 2
from all the elements of the third row. The elements of third row would be:
A[2][0] = ∞ - 2 = ∞
A[2][1] = ∞ - 2 = ∞
A[2][2] = ∞ - 2 = ∞
A[2][3] = ∞ - 2 = ∞
A[2][4] = 2 - 2 = 0
Since fifth row does not contain any zero value so we will find the minimum value of the fifth row. The
minimum value of the fifth row is 11 so we subtract 11 from all the elements of the fifth row.
A[4][0] = 11 - 11 = 0
A[4][1] = ∞ - 11 = ∞
A[4][2] = ∞ - 11 = ∞
A[4][3] = ∞ - 11 = ∞
A[4][4] = ∞ - 11 = ∞
The total minimum cost is (11 + 2) equals to 13. The cost of reduction of node 3 is c(2, 3) + r + r` = 11 + 28 + 13 =
52.
Consider the path from node 2 to node 5. Make the fourth row and third column as infinity. Since we cannot
move back from the node 5 to node 1 so make 1 to 5 also as infinity as shown in the below matrix:
Now we will check whether any row contains zero value or not. Since every row and column contains a zero
value; therefore, the above matrix is the reduced matrix.
The cost of reduction of node 5 is c(2, 5) + r + r` = 0 + 28 + 0 = 28
Now we will find out the leaf node with a minimum cost. The node 5 with a cost 28 is minimum so we select
node 5 for the further exploration. The node 5 can be further expanded to the node 3 as shown in the below
figure:
Here, we will use the matrix of node 5 having cost 28 as shown below:
Consider the path from node 5 to node 3. Make the fifth row and third column as infinity. Since we cannot
move back from the node 3 to node 1 so make 1 to 5 also as infinity as shown in the below matrix:
Now we will check whether any row contains zero value or not. Since every row and column contains a zero
value; therefore, the above matrix is the reduced matrix.
The cost of reduction of node 3 is c(5, 3) + r + r` = 0 + 28 + 0 = 28.
Finally, we traverse all the nodes. The upper value is updated from infinity to 28. We will check whether any
leaf node has a value less than 28. Since no leaf node contains the value less than 28 so we discard all the leaf
nodes from the tree as shown below:
The path of the tour would be 1->4->2->5->3.
O/1 Knapsack Problem
What is Knapsack Problem: Knapsack problem is a problem in combinatorial optimization,
Given a set of items, each with a mass & a value, determine the number of each item to
include in a collection so that the total weight is less than or equal to a given limit & the total
value is as large as possible.
O-1 Knapsack Problem can formulate as. Let there be n items, Z1 to Zn where Zi has value
37
Pi & weight wi
. The maximum weight that can carry in the bag is m.
All values and weights are non negative.
Maximize the sum of the values of the items in the knapsack, so that sum of the weights must
be less than the knapsack’s capacity m.
The formula can be stated as
Xi=0 or 1 1 ≤ i ≤ n
To solve o/1 knapsack problem using B&B:
Knapsack is a maximization problem
Replace the objective function by the function to make it into a
minimization problem
The modified knapsack problem is stated as
Fixed tuple size solution space:
o Every leaf node in state space tree represents an answer for which
is an answer node; other leaf nodes are infeasible
o For optimal solution, define
for every answer node x
For infeasible leaf nodes,
For non leaf nodes
c(x) = min{c(lchild(x)), c(rchild(x))}
Define two functions cˆ(x) and u(x) such that for every
node x,
cˆ(x) ≤ c(x) ≤ u(x)
Computing cˆ(·) and u(·)
Algorithm ubound ( cp, cw, k, m )
{
// Input: cp: Current profit total
// Input: cw: Current weight total
// Input: k: Index of last removed item
// Input: m: Knapsack capacity
b=cp; c=cw;
for i:=k+1 to n do{
if(c+w[i] ≤ m) then {
c:=c+w[i]; b=b-p[i];
}
}
return b;
}
Solving an Example
Consider the problem with n =4, V = {10, 10, 12, 18}, w = {2, 4, 6, 9} and W = 15. Here, we calculate the initital
upper bound to be U = 10 + 10 + 12 = 32. Note that the 4th object cannot be included here, since that would
exceed W. For the cost, we add 3/9 th of the final value, and hence the cost function is 38. Remember to
negate the values after calculation before comparison.
After calculating the cost at each node, kill nodes that do not need exploring. Hence, the final state space tree
will be as follows (Here, the number of the node denotes the order in which the state space tree was explored):
38
Note here that node 3 and node 5 have been killed after updating U at node 7. Also, node 6 is not explored
further, since adding any more weight exceeds the threshold. At the end, only nodes 6 and 8 remain. Since the
value of U is less for node 8, we select this node. Hence the solution is {1, 1, 0, 1}, and we can see here that the
total weight is exactly equal to the threshold value in this case.
39