BACKTRACKING
BACKTRACKING
3: BACKTRACKING Date:18/04/2023
THEORY:
Backtracking is a general algorithmic technique used to systematically search for solutions to
combinatorial problems. It is based on the idea of incrementally building a solution by
exploring all possible options and backtracking when a partial solution cannot be extended to
a complete solution.
The backtracking algorithm works as follows:
1. Start with an empty partial solution.
2. Choose the next element or option that can be added to the partial solution.
3. Check if the chosen element violates any constraints or conditions. If it does, discard it and
go back to step 2 (backtrack).
4. If the chosen element is valid, add it to the partial solution.
5. If the partial solution is complete (meets all the requirements), record it as a valid solution.
6. Recursively repeat steps 2-5 with the updated partial solution.
7. If all options have been explored, backtrack to the previous step and continue exploring
other options.
Backtracking is particularly useful for solving problems with a large search space where a
systematic exploration of all possible solutions is necessary. By eliminating invalid options
early in the process, backtracking reduces the number of unnecessary computations, making
it more efficient than exhaustive enumeration.
One of the key components of a backtracking algorithm is the decision-making process at
each step. The selection of the next option to consider can greatly affect the efficiency and
correctness of the algorithm. Careful consideration of constraints and heuristics can guide the
decision-making process and lead to more effective backtracking.
Backtracking is commonly used to solve various combinatorial problems, such as the n-
queens problem, Sudoku puzzles, graph coloring, subset sum problem, and many other
constraint satisfaction problems. It is a fundamental technique in algorithm design and is
often combined with other techniques, such as pruning or memoization, to further optimize
the search process.
However, it is important to note that backtracking can have an exponential time complexity
in the worst case, as it may need to explore all possible combinations. In such cases,
additional optimizations or alternative algorithms may be required to improve the
performance.
Algorithm:
Time complexity :
The time complexity of the N-Queens problem when solved using backtracking depends on
the specific implementation and the size of the chessboard (N).
In the N-Queens problem, the goal is to place N queens on an N×N chessboard in such a way
that no two queens threaten each other. Backtracking is a common approach to solve this
In the worst case, the backtracking algorithm for the N-Queens problem has an exponential
time complexity. This is because the algorithm explores all possible configurations of queen
placements, resulting in a branching factor of N at each level of the recursion. The worst-
case scenario occurs when there are no restrictions on the placements or symmetries in the
chessboard.
Therefore, the worst-case time complexity of the backtracking algorithm for the N-Queens
problem is O(N!), where N is the size of the chessboard. This exponential time complexity
arises from the exponential growth in the number of recursive calls and the branching factor
at each level.
SPACE COMPLEXITY :
The space complexity of the N-Queens problem when solved using backtracking depends on
the specific implementation and how the algorithm stores and tracks data during the
recursion.
Additionally, the algorithm may use additional space to store the current state of the queen
placements and track the valid positions. The space required for this state tracking typically
grows linearly with the number of queens or the size of the chessboard, so it contributes
O(N) space complexity.
Therefore, the overall space complexity of the basic backtracking implementation for the N-
Queens problem is O(N) in the worst case.
CODE :
/*code for N queen’s problem*/
#include <stdio.h>
#define N 20
int M[N],i,j;
void print(int n)
{int j;
printf("\n\n");
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++)
{
if (M[i] == j)
printf("\tQ");
else
printf("\t_");
}
};
printf("\n\n");
}
int main()
{
int n;
printf("Enter the size(n):");
scanf("%d", &n);
nqueen(1, n);
return 0;
}
OUTPUT :
1 _ Q _ _
2 _ _ _ Q
3 Q _ _ _
4 _ _ Q _
1 2 3 4
1 _ _ Q _
2 Q _ _ _
3 _ _ _ Q
4 _ Q _ _
--------------------------------
Process exited after 1.314 seconds with return value 0
Press any key to continue . . .
Write a c program to implement SUM OF SUBSETS algorithm for the following problem:
Given ‘n’ weights, find the combinations of these weights such that the total weight of the
subset equal to ‘m’ (where n and m are given)
Algorithm
Time complexity :
The time complexity of the Subset Sum problem depends on the specific algorithm used to
solve it. There are several approaches to solving Subset Sum, and the time complexity can
vary depending on the chosen method.
The backtracking approach explores different combinations of elements to construct subsets
and backtracks when the sum exceeds the target or all elements have been considered. In the
worst case, the backtracking approach has an exponential time complexity of O(2^n), where
n is the number of elements in the input set. However, the actual running time can be
improved with pruning techniques and heuristics.
Code
int n, m,i;
if (s + w[k] == m)
print(w, k, x);
else if ((s + w[k] + w[k + 1]) <= m)
sumofsub(s + w[k], k + 1, r, w, x);
if (((s + r - w[k]) >= m) && (s + w[k + 1] <= m))
int main()
{
int r = 0;
OUTPUT :
C:\Users\ Nidhi Shanbhag \Downloads\madf CODES\sumofsubsets.exe
Enter the number of elements: 6
Enter the elements
5
10
12
13
15
18
Enter max weight: 30
( 1, 1, 0, 0, 1, ) ie. sum of the subset ( 5, 10, 15, )
( 1, 0, 1, 1, ) ie. sum of the subset ( 5, 12, 13, )
( 0, 0, 1, 0, 0, 1, ) ie. sum of the subset ( 12, 18, )
--------------------------------
Process exited after 6.7 seconds with return value 0
Press any key to continue . . .
Given below are the time slots of taxis. Only one taxi is available for the service at a time.
Find the most efficient way to schedule the appointment:
10
ALGORITHM :
Time complexity :
The time complexity of the m-coloring problem when solved using backtracking depends on
the specific implementation and characteristics of the graph being considered.
In the m-coloring problem, the goal is to color the vertices of a graph with at most m colors,
such that no adjacent vertices have the same color. The backtracking algorithm explores
different color assignments for each vertex and backtracks when it encounters a conflict.
In the worst case, the backtracking algorithm for the m-coloring problem has an exponential
time complexity. This is because the algorithm explores all possible color assignments for
each vertex, resulting in a branching factor of m at each level of the recursion. The worst-
case scenario occurs when every vertex has m possible colors to choose from.
Therefore, the worst-case time complexity of the backtracking algorithm for the m-coloring
problem is O(m^n), where n is the number of vertices in the graph. This exponential time
complexity arises from the exponential growth in the number of recursive calls and the
branching factor at each level.
Space complexity :
The space complexity of the m-coloring problem when solved using backtracking depends on
the specific implementation and how the algorithm stores and tracks data during the
recursion.
In a basic backtracking implementation, the space complexity is determined by the maximum
depth of the recursion, which corresponds to the number of vertices in the graph. This is
because each recursive call creates a new stack frame, which includes local variables,
parameters, and return addresses.
Additionally, the algorithm may use additional space to store the current state of the coloring
and track the colors assigned to each vertex. The space required for this coloring state
tracking typically grows linearly with the number of vertices, so it contributes O(n) space
complexity.
Code:
#include <stdio.h>
#define N 20
} while (1);
}
OUTPUT :
Algorithm:
Time complexity :
The time complexity of the Hamiltonian cycle problem when solved using backtracking
depends on the specific implementation and characteristics of the graph being considered.
In the worst case, the backtracking algorithm for finding a Hamiltonian cycle has an
exponential time complexity. This is because the algorithm explores all possible
permutations of the vertices to construct a cycle and checks whether each permutation
satisfies the conditions of a Hamiltonian cycle.
The number of possible permutations of n vertices is n!, which grows factorially with the
number of vertices. Therefore, the worst-case time complexity of the backtracking algorithm
for finding a Hamiltonian cycle is O(n!).
Space complexity ;
The space complexity of the Hamiltonian cycle problem when solved using backtracking depends on
the specific implementation and how the algorithm stores and tracks data during the recursion.
In a basic backtracking implementation, the space complexity is determined by the maximum depth
of the recursion, which corresponds to the number of vertices in the graph. This is because each
recursive call creates a new stack frame, which includes local variables, parameters, and return
addresses.
Additionally, the algorithm may use additional space to maintain the current path or cycle being
constructed during the recursion. The space required for this path tracking typically grows linearly
with the number of vertices, so it contributes O(n) space complexity.
Therefore, the overall space complexity of the basic backtracking implementation for the
Hamiltonian cycle problem is O(n) in the worst case.
Code
int main()
{
int nodes, edges, o, d, x[N];
printf("Enter the number of nodes: "), scanf("%d",&nodes);
OUTPUT :
--------------------------------
Process exited after 47.15 seconds with return value 0
Press any key to continue . . .
N=4
M=8
p1,p2,p3,p4={3,5,6,10}
w1,w2,w3,w4}={2,3,4,5,}
Algorithm;
}
return b;
}
int main()
{
int profit=0, weight=0;
printf("Enter number of objects[n]: ");
scanf("%d",&n);
printf("Enter sack size[m]: ");
return 0;
}
OUTPUT :
C:\Users\ Nidhi Shanbhag \Downloads\madf CODES\knapsack_bt.exe
Enter number of objects[n]: 4
Enter sack size[m]: 8
Enter profits :
P[1]: 3
P[2]: 5
P[3]: 6
P[4]: 10
Enter weights :
W[1]: 2
W[2]: 3
W[3]: 4
W[4]: 5
MAX Profit = 13
Weight Occupied = 7
--------------------------------
Process exited after 19.19 seconds with return value 0
Press any key to continue . . .