DAA Module 2
DAA Module 2
Brute-Force
• Many problems solved in day-to-day life using the brute force strategy, for example
exploring all the paths to a nearby market to find the minimum shortest path.
• Arranging the books in a rack using all the possibilities to optimize the rack spaces,
etc.
o Optimizing: In this case, the best solution is found. To find the best solution, it
may either find all the possible solutions to find the best solution or if the value of
the best solution is known, it stops finding when the best solution is found. For
example: Finding the best path for the travelling salesman problem. Here best path
means that travelling all the cities and the cost of travelling should be minimum.
o Satisficing: It stops finding the solution as soon as the satisfactory solution is
found. Or example, finding the travelling salesman path which is within 10% of
optimal.
o Often Brute force algorithms require exponential time. Various heuristics and
optimization can be used:
o Heuristic: A rule of thumb that helps you to decide which possibilities we should
look at first.
o Optimization: A certain possibilities are eliminated without exploring all of them.
Suppose we have converted the problem in the form of the tree shown as below:
Brute force search considers each and every state of a tree, and the state is represented
in the form of a node. As far as the starting position is concerned, we have two choices,
i.e., A state and B state. We can either generate state A or state B. In the case of B state, we
have two states, i.e., state E and F.
In the case of brute force search, each state is considered one by one. As we can observe
in the above tree that the brute force search takes 12 steps to find the solution.
On the other hand, backtracking, which uses Depth-First search, considers the below
states only when the state provides a feasible solution. Consider the above tree, start from
the root node, then move to node A and then node C. If node C does not provide the
feasible solution, then there is no point in considering the states G and H. We backtrack
from node C to node A. Then, we move from node A to node D. Since node D does not
provide the feasible solution, we discard this state and backtrack from node D to node A.
We move to node B, then we move from node B to node E. We move from node E to node
K; Since k is a solution, so it takes 10 steps to find the solution. In this way, we eliminate
a greater number of states in a single iteration. Therefore, we can say that backtracking
is faster and more efficient than the brute force approach.
o This algorithm finds all the possible solutions, and it also guarantees that it finds the
correct solution to a problem.
o This type of algorithm is applicable to a wide range of domains.
o It is mainly used for solving simpler and small problems.
o It can be considered a comparison benchmark to solve a simple problem and does not
require any particular domain knowledge.
Disadvantages of a brute-force algorithm
The following are the disadvantages of the brute-force algorithm:
Greedy Algorithm
The greedy method is one of the strategies like Divide and conquer used to solve the
problems. This method is used for solving optimization problems. An optimization
problem is a problem that demands either maximum or minimum results. Let's
understand through some terms.
The Greedy method is the simplest and straightforward approach. It is not an algorithm,
but it is a technique. The main function of this approach is that the decision is taken
on the basis of the currently available information. Whatever the current
information is present, the decision is made without worrying about the effect of
the current decision in future.
This technique is basically used to determine the feasible solution that may or may not
be optimal. The feasible solution is a subset that satisfies the given criteria. The optimal
solution is the solution which is the best and the most favourable solution in the subset.
In the case of feasible, if more than one solution satisfies the given criteria then those
solutions will be considered as the feasible, whereas the optimal solution is the best
solution among all the solutions.
o To construct the solution in an optimal way, this algorithm creates two sets where one
set contains all the chosen items, and another set contains the rejected items.
o A Greedy algorithm makes good local choices in the hope that the solution should be
either feasible or optimal.
The above is the greedy algorithm. Initially, the solution is assigned with zero value. We
pass the array and number of elements in the greedy algorithm. Inside the for loop, we
select the element one by one and checks whether the solution is feasible or not. If the
solution is feasible, then we perform the union.
P:A→B
The problem is that we have to travel this journey from A to B. There are various
solutions to go from A to B. We can go from A to B by walk, car, bike, train, aeroplane,
etc. There is a constraint in the journey that we have to travel this journey within 12
hrs. If I go by train or aeroplane then only, I can cover this distance within 12 hrs. There
are many solutions to this problem but there are only two solutions that satisfy the
constraint.
If we say that we have to cover the journey at the minimum cost. This means that we have
to travel this distance as minimum as possible, so this problem is known as a
minimization problem. Till now, we have two feasible solutions, i.e., one by train and
another one by air. Since travelling by train will lead to the minimum cost so it is an
optimal solution. An optimal solution is also the feasible solution, but providing the
best result so that solution is the optimal solution with the minimum cost. There would
be only one optimal solution.
The problem that requires either minimum or maximum result then that problem is
known as an optimization problem. Greedy method is one of the strategies used for
solving the optimization problems.
It follows the local optimum choice at each stage with a intend of finding the global
optimum. Let's understand through an example.
Consider the graph which is given below:
We have to travel from the source to the destination at the minimum cost. Since we have
three feasible solutions having cost paths as 10, 20, and 5. 5 is the minimum cost path so
it is the optimal solution. This is the local optimum, and in this way, we find the local
optimum at each stage in order to calculate the global optimal solution.
What is Backtracking?
Backtracking is nothing but the modified process of the Brute force approach. It is a
technique where multiple solutions to a problem are available, and it searches for the
solution to the problem among all the available options. Let's consider the example of
brute force search as backtracking follows the brute force search approach.
Consider the box, and we have three objects of three different colors. One object is of red
color, the second object is of green color, and the third object is of blue color. Now, we
have to keep these objects inside the box, and we have multiple options. As per the Brute
force approach, we have to consider all the options and identify the best option among all
the possible options.
Suppose we first fill red object, after then green object and then blue object. This is the
first solution to this problem. The possible solution is red, green, and blue.
The second solution is to keep the red object, then the blue object, and then the green
object. The possible solution red, blue, and green.
The third solution can be to keep the green object, then the red object and then the blue
object. The possible solution is green, red and blue.
The fourth solution is to keep the green object, then the blue object and then the red
object. The possible solution is green, blue and red.
The fifth solution is to keep the blue object, then green object and then red object. The
possible solution is blue, green and red.
The sixth solution is to keep the blue object, then the red object and then the green object.
The possible solution is blue, red and green.
The above are the possible solutions, and we have to identify the best possible solution
out of all the possible solutions. This approach is known as a brute force approach.
Backtracking is similar to the brute force approach, but it is a modified process of the
brute force approach.
Let's see how backtracking is different from the brute force approach.
The above is the figure that shows the possible solutions to the above problem. Now we
will see that how these solutions are represented in backtracking.
In backtracking, solutions are represented in the form of a tree and that tree is known as
a state space tree. Since backtracking follows the DFS, the tree will be formed using DFS,
which is known as a State Space tree.
Consider the first solution, i.e., red, green, blue, and it can be represented in the form of
a tree as shown as below.
Consider the first solution, i.e., red, green, blue, and it can be represented in the form of
a tree as shown as below.
Consider the second solution, i.e., red, blue, green. Since there is no more object after
blue so we will backtrack and move to the green. Instead of taking green, we first take
blue and then green, shown as below:
The next solution is green, red and blue. Since we cannot explore the green object, so
we move back and reach the blue object. We cannot explore the blue object, so we again
move back and reach to the red object. Instead of using the red object, we will use the
green object. After the green object, we use the red object and then we use the blue
object. We cannot explore the blue object further. Now the sequence green, red and blue
is formed as shown as below:
The next solution is green, blue and red. Since we cannot explore the blue object, we
move back and reach the red object. Instead of using a red color object, we will use the
blue color object and then we use the red color object. Now the sequence green, blue and
red is formed.
The next solution is blue, green and red. Since we cannot explore the red object, so we
backtrack and reach the blue object. We cannot explore the blue object so we backtrack
and reach the green object. Instead of using the green object, we will use the blue color
object then we use the green object and then we use the red color object. The sequence,
i.e., blue, green and red, is formed as shown as below:
The next solution is blue, red and green. Since we cannot explore red object so we
backtrack and reach to the green object. Instead of using the green object, we use the red
object and then we use the green object.
The above is the state space tree that shows all the possible solutions related to the
problem. Therefore, we can say that the state space tree can be used to represent all the
solutions in backtracking. Using backtracking, we can solve the problem that has some
constraints and we can find the solution based on these constraints. Suppose in the
above example; the constraint is blue color object must not be in the middle (bounding
function).
The first solution is red, green and blue. Since blue color object is not in the middle so
we do need to perform any modification.
The second solution is red, blue, and green. Since blue color is in the middle so we will
remove the green color as shown as below:
The next solution is green, red, and blue. Since blue color object is not in the middle so
we do need to perform any modification.
The next solution is green, blue and red. Since blue color is in the middle so we will
remove the red color as shown as below:
The above is the state space tree that does not have blue object in the middle of the
solution.
It is similar to backtracking. The concept branch and bound and backtracking follow the
Brute force method and generate the state space tree. But both of them follows different
approaches. The way to generate the tree is different.
Backtracking follows the DFS, whereas the branch n bound follows the BFS to generate
the tree. Now we will understand the branch n bound through an example. As it follows
the BFS, so first all the nodes of the same level are added then we move to the next level.
Now we have three possibilities that either we select red, green, or blue objects as shown
below. In this case, we have completed the first level.
Now we move to the next level.
In the case of red object, we have two possibilities that either we select green or blue
object shown as below:
In the case of green object, we have two possibilities that either we select red or blue
object shown as below:
In the case of blue object, we have two possibilities that either we select red or green
object shown as below:
We move to the third level.
In the case of a green object, only one object, i.e., blue, can be added.
In the case of a blue object, only one object, i.e., green, can be added.
In the case of a red object, only one object, i.e., blue, can be added.
In the case of a blue object, only one object, i.e., red, can be added.
In the case of a green object, only one object, i.e., red, can be added.
In the case of a red object, only one object, i.e., green, can be added.
Examples:
o 8 Queens problem
o Knapsack problem using backtracking
The problem that can be solved by using branch and bound is:
When we find the solution using backtracking When we find the solution using
then some bad choices can be made. Branch n bound then it provides a
better solution so there are no
chances of making a bad choice.
The state space tree is searched until the The state space tree needs to be
solution of the problem is obtained. searched completely as the optimum
solution can be present anywhere in
the state space tree.
In backtracking, all the possible solutions are In branch and bound, based on
tried. If the solution does not satisfy the search; bounding values are
constraint, then we backtrack and look for calculated. According to the bounding
another solution. values, we either stop there or extend.
Backtracking is more efficient than the Branch Branch n bound is less efficient.
and bound.
Backtracking solves the given problem by first Branch and bound solves the given
finding the solution of the subproblem and then problem by dividing the problem into
recursively solves the other problems based on two atleast subproblems.
the solution of the first subproblem.
Bin Packing Problem (Minimize
number of used Bins)
iven n items of different weights and bins each of capacity c, assign each
item to a bin such that number of total used bins is minimized. It may be
assumed that all items have weights smaller than bin capacity.
Example:
Input: weight[] = {4, 8, 1, 4, 2, 1}
Bin Capacity c = 10
Output: 2
We need minimum 2 bins to accommodate all items
First bin contains {4, 4, 2} and second bin {8, 1, 1}
res = 0
rem = c
for _ in range(len(weight)):
else:
res += 1
rem = c - weight[_]
return res
# Driver Code
weight = [2, 5, 4, 7, 1, 3, 8]
c = 10
nextfit(weight, c))
Output:
Number of bins required in Next Fit : 4
Next Fit is a simple algorithm. It requires only O(n) time and O(1) extra
space to process n items.
Next Fit is 2 approximate, i.e., the number of bins used by this algorithm is
bounded by twice of optimal. Consider any two adjacent bins. The sum of
items in these two bins must be > c; otherwise, NextFit would have put all
the items of second bin into the first. The same holds for all other bins.
Thus, at most half the space is wasted, and so Next Fit uses at most 2M
bins if M is optimal.
2. First Fit:
When processing the next item, scan the previous bins in order and place
the item in the first bin that fits. Start a new bin only if it does not fit in any of
the existing bins.
• C++
• Java
• Python3
• C#
• Javascript
# online algorithm
res = 0
bin_rem = [0]*n
# Place items one by one
for i in range(n):
# weight[i]
j =0
break
j+=1
if (j == res):
bin_rem[res] = c - weight[i]
res= res+1
return res
# Driver program
weight = [2, 5, 4, 7, 1, 3, 8]
c = 10
n = len(weight)
print("Number of bins required in First Fit : ",firstFit(weight, n, c))
Output:
Number of bins required in First Fit : 4
The above implementation of First Fit requires O(n 2) time, but First Fit can
be implemented in O(n Log n) time using Self-Balancing Binary Search
Trees.
If M is the optimal number of bins, then First Fit never uses more than 1.7M
bins. So First-Fit is better than Next Fit in terms of upper bound on number
of bins.
3. Best Fit:
The idea is to places the next item in the *tightest* spot. That is, put it in the
bin so that the smallest empty space is left.
• C++
• Java
• Python3
• C#
• Javascript
# online algorithm
res = 0;
bin_rem = [0]*n;
for i in range(n):
# can accommodate
# weight[i]
j = 0;
# of best bin
min = c + 1;
bi = 0;
for j in range(res):
bi = j;
if (min == c + 1):
bin_rem[res] = c - weight[i];
res += 1;
bin_rem[bi] -= weight[i];
return res;
# Driver code
if __name__ == '__main__':
weight = [ 2, 5, 4, 7, 1, 3, 8 ];
c = 10;
n = len(weight);
print("Number of bins required in First Fit : ",
firstFit(weight, n, c));
Output:
Number of bins required in Best Fit : 4
Best Fit can also be implemented in O(n Log n) time using Self-Balancing
Binary Search Trees.
If M is the optimal number of bins, then Best Fit never uses more than 1.7M
bins. So Best Fit is same as First Fit and better than Next Fit in terms of
upper bound on number of bins.
4. Worst Fit:
The idea is to places the next item in the least tight spot to even out the
bins. That is, put it in the bin so that most empty space is left.
• C++
• Java
• Python3
• C#
• Javascript
# Python program to find number of bins required using# Worst fit algorithm.# Returns
number of bins required using worst fit# online algorithm
res = 0
# Create an array to store remaining space in bins
for i in range(n):
# weight[i]
# of worst bin
mx,wi = -1,0
for j in range(res):
wi = j
mx = bin_rem[j] - weight[i]
if (mx == -1):
bin_rem[res] = c - weight[i]
res += 1
bin_rem[wi] -= weight[i]
return res
# Driver program
weight = [ 2, 5, 4, 7, 1, 3, 8 ]
c = 10
n = len(weight)
Output:
Number of bins required in Worst Fit : 4
Worst Fit can also be implemented in O(n Log n) time using Self-Balancing
Binary Search Trees.
If M is the optimal number of bins, then Best Fit never uses more than 2M-2
bins. So Worst Fit is same as Next Fit in terms of upper bound on number of
bins.
Offline Algorithms
In the offline version, we have all items upfront. Unfortunately offline version
is also NP Complete, but we have a better approximate algorithm for it. First
Fit Decreasing uses at most (4M + 1)/3 bins if the optimal is M.
4. First Fit Decreasing:
A trouble with online algorithms is that packing large items is difficult,
especially if they occur late in the sequence. We can circumvent this by
*sorting* the input sequence, and placing the large items first. With sorting,
we get First Fit Decreasing and Best Fit Decreasing, as offline analogues of
online First Fit and Best Fit.
• C++
• Java
• Python3
• C#
• Javascript
# online algorithm
res = 0
bin_rem = [0]*n
# Place items one by one
for i in range(n):
# weight[i]
j =0
break
j+=1
if (j == res):
bin_rem[res] = c - weight[i]
res= res+1
return res
[Link](reverse = True)
return firstFit(weight, n, c)
# Driver program
weight = [ 2, 5, 4, 7, 1, 3, 8 ]
c = 10
n = len(weight)
Output:
Number of bins required in First Fit Decreasing : 3
First Fit decreasing produces the best result for the sample input because
items are sorted first.
First Fit Decreasing can also be implemented in O(n Log n) time using Self-
Balancing Binary Search Trees.
Knapsack problem
Here knapsack is like a container or a bag. Suppose we have given some items which
have some weights or profits. We have to put some items in the knapsack in such a
way total value produces a maximum profit.
For example, the weight of the container is 20 kg. We have to select the items in such
a way that the sum of the weight of items should be either smaller than or equal to
the weight of the container, and the profit should be maximum.
We will discuss both the problems one by one. First, we will learn about the 0/1
knapsack problem.
Play Video
Weights: {3, 4, 6, 5}
Profits: {2, 3, 1, 4}
xi = {1, 0, 0, 1}
= {0, 0, 0, 1}
= {0, 1, 0, 1}
The above are the possible combinations. 1 denotes that the item is completely
picked and 0 means that no item is picked. Since there are 4 items so possible
combinations will be:
24 = 16; So. There are 16 possible combinations that can be made by using the above
problem. Once all the combinations are made, we have to select the combination
that provides the maximum profit.
0 1 2 3 4 5 6 7 8
In the above matrix, columns represent the weight, i.e., 8. The rows represent the
profits and weights of items. Here we have not taken the weight 8 directly, problem
is divided into sub-problems, i.e., 0, 1, 2, 3, 4, 5, 6, 7, 8. The solution of the sub-
problems would be saved in the cells and answer to the problem would be stored in
the final cell. First, we write the weights in the ascending order and profits according
to their weights shown as below:
wi = {3, 4, 5, 6}
pi = {2, 3, 4, 1}
The first row and the first column would be 0 as there is no item for w=0
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0
2 0
3 0
4 0
w1 = 3; Since we have only one item in the set having weight 3, but the capacity of
the knapsack is 1. We cannot fill the item of 3kg in the knapsack of capacity 1 kg so
add 0 at M[1][1] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0
2 0
3 0
4 0
When i = 1, W = 2
w1 = 3; Since we have only one item in the set having weight 3, but the capacity of
the knapsack is 2. We cannot fill the item of 3kg in the knapsack of capacity 2 kg so
add 0 at M[1][2] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0
2 0
3 0
4 0
w1 = 3; Since we have only one item in the set having weight equal to 3, and weight
of the knapsack is also 3; therefore, we can fill the knapsack with an item of weight
equal to 3. We put profit corresponding to the weight 3, i.e., 2 at M[1][3] shown as
below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2
2 0
3 0
4 0
When i=1, W = 4
W1 = 3; Since we have only one item in the set having weight equal to 3, and weight
of the knapsack is 4; therefore, we can fill the knapsack with an item of weight equal
to 3. We put profit corresponding to the weight 3, i.e., 2 at M[1][4] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2
2 0
3 0
4 0
When i=1, W = 5
W1 = 3; Since we have only one item in the set having weight equal to 3, and weight
of the knapsack is 5; therefore, we can fill the knapsack with an item of weight equal
to 3. We put profit corresponding to the weight 3, i.e., 2 at M[1][5] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2
2 0
3 0
4 0
W1 = 3; Since we have only one item in the set having weight equal to 3, and weight
of the knapsack is 6; therefore, we can fill the knapsack with an item of weight equal
to 3. We put profit corresponding to the weight 3, i.e., 2 at M[1][6] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2
2 0
3 0
4 0
When i=1, W = 7
W1 = 3; Since we have only one item in the set having weight equal to 3, and weight
of the knapsack is 7; therefore, we can fill the knapsack with an item of weight equal
to 3. We put profit corresponding to the weight 3, i.e., 2 at M[1][7] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2
2 0
3 0
4 0
When i =1, W =8
W1 = 3; Since we have only one item in the set having weight equal to 3, and weight
of the knapsack is 8; therefore, we can fill the knapsack with an item of weight equal
to 3. We put profit corresponding to the weight 3, i.e., 2 at M[1][8] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0
3 0
4 0
When i =2, W = 1
The weight corresponding to the value 2 is 4, i.e., w2 = 4. Since we have only one
item in the set having weight equal to 4, and the weight of the knapsack is 1. We
cannot put the item of weight 4 in a knapsack, so we add 0 at M[2][1] shown as
below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0
3 0
4 0
When i =2, W = 2
The weight corresponding to the value 2 is 4, i.e., w2 = 4. Since we have only one
item in the set having weight equal to 4, and the weight of the knapsack is 2. We
cannot put the item of weight 4 in a knapsack, so we add 0 at M[2][2] shown as
below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0
3 0
4 0
When i =2, W = 3
The weight corresponding to the value 2 is 4, i.e., w2 = 4. Since we have two items in
the set having weights 3 and 4, and the weight of the knapsack is 3. We can put the
item of weight 3 in a knapsack, so we add 2 at M[2][3] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2
3 0
4 0
When i =2, W = 4
The weight corresponding to the value 2 is 4, i.e., w2 = 4. Since we have two items in
the set having weights 3 and 4, and the weight of the knapsack is 4. We can put item
of weight 4 in a knapsack as the profit corresponding to weight 4 is more than the
item having weight 3, so we add 3 at M[2][4] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3
3 0
4 0
When i = 2, W = 5
The weight corresponding to the value 2 is 4, i.e., w2 = 4. Since we have two items in
the set having weights 3 and 4, and the weight of the knapsack is 5. We can put item
of weight 4 in a knapsack and the profit corresponding to weight is 3, so we add 3
at M[2][5] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3
3 0
4 0
When i = 2, W = 6
The weight corresponding to the value 2 is 4, i.e., w2 = 4. Since we have two items in
the set having weights 3 and 4, and the weight of the knapsack is 6. We can put item
of weight 4 in a knapsack and the profit corresponding to weight is 3, so we add 3
at M[2][6] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3
3 0
4 0
When i = 2, W = 7
The weight corresponding to the value 2 is 4, i.e., w2 = 4. Since we have two items in
the set having weights 3 and 4, and the weight of the knapsack is 7. We can put item
of weight 4 and 3 in a knapsack and the profits corresponding to weights are 2 and
3; therefore, the total profit is 5, so we add 5 at M[2][7] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 0 3 3 3 5
3 0
4 0
When i = 2, W = 8
The weight corresponding to the value 2 is 4, i.e., w2 = 4. Since we have two items in
the set having weights 3 and 4, and the weight of the knapsack is 7. We can put item
of weight 4 and 3 in a knapsack and the profits corresponding to weights are 2 and
3; therefore, the total profit is 5, so we add 5 at M[2][7] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0
4 0
When i = 3, W = 1
The weight corresponding to the value 3 is 5, i.e., w3 = 5. Since we have three items
in the set having weights 3, 4, and 5, and the weight of the knapsack is 1. We cannot
put neither of the items in a knapsack, so we add 0 at M[3][1] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0
4 0
When i = 3, W = 2
The weight corresponding to the value 3 is 5, i.e., w3 = 5. Since we have three items
in the set having weight 3, 4, and 5, and the weight of the knapsack is 1. We cannot
put neither of the items in a knapsack, so we add 0 at M[3][2] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0
4 0
When i = 3, W = 3
The weight corresponding to the value 3 is 5, i.e., w3 = 5. Since we have three items
in the set of weight 3, 4, and 5 respectively and weight of the knapsack is 3. The item
with a weight 3 can be put in the knapsack and the profit corresponding to the item
is 2, so we add 2 at M[3][3] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 2
4 0
When i = 3, W = 4
The weight corresponding to the value 3 is 5, i.e., w3 = 5. Since we have three items
in the set of weight 3, 4, and 5 respectively, and weight of the knapsack is 4. We can
keep the item of either weight 3 or 4; the profit (3) corresponding to the weight 4 is
more than the profit corresponding to the weight 3 so we add 3 at M[3][4] shown
as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 1 3
4 0
When i = 3, W = 5
The weight corresponding to the value 3 is 5, i.e., w3 = 5. Since we have three items
in the set of weight 3, 4, and 5 respectively, and weight of the knapsack is 5. We can
keep the item of either weight 3, 4 or 5; the profit (3) corresponding to the weight
4 is more than the profits corresponding to the weight 3 and 5 so we add 3 at
M[3][5] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 1 3 3
4 0
When i =3, W = 6
The weight corresponding to the value 3 is 5, i.e., w3 = 5. Since we have three items
in the set of weight 3, 4, and 5 respectively, and weight of the knapsack is 6. We can
keep the item of either weight 3, 4 or 5; the profit (3) corresponding to the weight
4 is more than the profits corresponding to the weight 3 and 5 so we add 3 at
M[3][6] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 1 3 3 3
4 0
When i =3, W = 7
The weight corresponding to the value 3 is 5, i.e., w3 = 5. Since we have three items
in the set of weight 3, 4, and 5 respectively, and weight of the knapsack is 7. In this
case, we can keep both the items of weight 3 and 4, the sum of the profit would be
equal to (2 + 3), i.e., 5, so we add 5 at M[3][7] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 1 3 3 3 5
4 0
When i = 3, W = 8
The weight corresponding to the value 3 is 5, i.e., w3 = 5. Since we have three items
in the set of weight 3, 4, and 5 respectively, and the weight of the knapsack is 8. In
this case, we can keep both the items of weight 3 and 4, the sum of the profit would
be equal to (2 + 3), i.e., 5, so we add 5 at M[3][8] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 1 3 3 3 5 5
4 0
When i = 4, W = 1
The weight corresponding to the value 4 is 6, i.e., w4 = 6. Since we have four items
in the set of weights 3, 4, 5, and 6 respectively, and the weight of the knapsack is 1.
The weight of all the items is more than the weight of the knapsack, so we cannot
add any item in the knapsack; Therefore, we add 0 at M[4][1] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 1 3 3 3 5 5
4 0 0
When i = 4, W = 2
The weight corresponding to the value 4 is 6, i.e., w4 = 6. Since we have four items
in the set of weights 3, 4, 5, and 6 respectively, and the weight of the knapsack is 2.
The weight of all the items is more than the weight of the knapsack, so we cannot
add any item in the knapsack; Therefore, we add 0 at M[4][2] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 1 3 3 3 5 5
4 0 0 0
When i = 4, W = 3
The weight corresponding to the value 4 is 6, i.e., w4 = 6. Since we have four items
in the set of weights 3, 4, 5, and 6 respectively, and the weight of the knapsack is 3.
The item with a weight 3 can be put in the knapsack and the profit corresponding
to the weight 4 is 2, so we will add 2 at M[4][3] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 1 3 3 3 5 5
4 0 0 0 2
When i = 4, W = 4
The weight corresponding to the value 4 is 6, i.e., w4 = 6. Since we have four items
in the set of weights 3, 4, 5, and 6 respectively, and the weight of the knapsack is 4.
The item with a weight 4 can be put in the knapsack and the profit corresponding
to the weight 4 is 3, so we will add 3 at M[4][4] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 1 3 3 3 5 5
4 0 0 0 2 3
When i = 4, W = 5
The weight corresponding to the value 4 is 6, i.e., w4 = 6. Since we have four items
in the set of weights 3, 4, 5, and 6 respectively, and the weight of the knapsack is 5.
The item with a weight 4 can be put in the knapsack and the profit corresponding
to the weight 4 is 3, so we will add 3 at M[4][5] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 1 3 3 3 5 5
4 0 0 0 2 3 3
When i = 4, W = 6
The weight corresponding to the value 4 is 6, i.e., w4 = 6. Since we have four items
in the set of weights 3, 4, 5, and 6 respectively, and the weight of the knapsack is 6.
In this case, we can put the items in the knapsack either of weight 3, 4, 5 or 6 but the
profit, i.e., 4 corresponding to the weight 6 is highest among all the items; therefore,
we add 4 at M[4][6] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 1 3 3 3 5 5
4 0 0 0 2 3 3 4
When i = 4, W = 7
The weight corresponding to the value 4 is 6, i.e., w4 = 6. Since we have four items
in the set of weights 3, 4, 5, and 6 respectively, and the weight of the knapsack is 7.
Here, if we add two items of weights 3 and 4 then it will produce the maximum
profit, i.e., (2 + 3) equals to 5, so we add 5 at M[4][7] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 2 3 3 3 5 5
4 0 0 0 2 3 3 4 5
When i = 4, W = 8
The weight corresponding to the value 4 is 6, i.e., w4 = 6. Since we have four items
in the set of weights 3, 4, 5, and 6 respectively, and the weight of the knapsack is 8.
Here, if we add two items of weights 3 and 4 then it will produce the maximum
profit, i.e., (2 + 3) equals to 5, so we add 5 at M[4][8] shown as below:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 2 3 3 3 5 5
4 0 0 0 2 3 3 4 5 5
As we can observe in the above table that 5 is the maximum profit among all the
entries. The pointer points to the last row and the last column having 5 value. Now
we will compare 5 value with the previous row; if the previous row, i.e., i = 3
contains the same value 5 then the pointer will shift upwards. Since the previous
row contains the value 5 so the pointer will be shifted upwards as shown in the
below table:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 2 3 3 3 5 5
4 0 0 0 2 3 3 4 5 5
Again, we will compare the value 5 from the above row, i.e., i = 2. Since the above
row contains the value 5 so the pointer will again be shifted upwards as shown in
the below table:
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 2 3 3 3 5 5
4 0 0 0 2 3 3 4 5 5
Again, we will compare the value 5 from the above row, i.e., i = 1. Since the above
row does not contain the same value so we will consider the row i=1, and the weight
corresponding to the row is 4. Therefore, we have selected the weight 4 and we have
rejected the weights 5 and 6 shown below:
x = { 1, 0, 0}
0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 2 2 2 2 2 2
2 0 0 0 2 3 3 3 5 5
3 0 0 0 2 3 3 3 5 5
4 0 0 0 2 3 3 4 5 5
Again we compare the value 2 with a above row, i.e., i = 1. Since the row i =0 does
not contain the value 2, so row i = 1 will be selected and the weight corresponding
to the i = 1 is 3 shown below:
X = {1, 1, 0, 0}
0, 10, 0, 25, 25], [0, 15, 25, 0, 30], [0, 20, 25, 30,
0]]
# base case
return dist[1][i]
# memoization
if memo[i][mask] != -1:
return memo[i][mask]
return res
ans = 10**9
Output
The cost of most efficient tour = 80
Time Complexity : O(n2*2n)
Auxiliary Space : O(n2) , where n is number of Nodes/Cities here.
For a set of size n, we consider n-2 subsets each of size n-1 such that all
subsets don’t have nth in them. Using the above recurrence relation, we can
write a dynamic programming-based solution. There are at most O(n*2n)
subproblems, and each one takes linear time to solve. The total running
time is therefore O(n2*2n). The time complexity is much less than O(n!) but
still exponential. The space required is also exponential. So this approach is
also infeasible even for a slightly higher number of vertices.