0% found this document useful (0 votes)
45 views

Daa Lab Manual

The document describes implementing various algorithms using different algorithmic techniques like divide and conquer, decrease and conquer, and transform and conquer. It includes implementing recursive and non-recursive algorithms to study computational complexity orders from logarithmic to factorial time. Specific algorithms implemented include Strassen's matrix multiplication using divide and conquer approach and topological sorting using decrease and conquer approach. Program code is provided for examples.

Uploaded by

passion job
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
45 views

Daa Lab Manual

The document describes implementing various algorithms using different algorithmic techniques like divide and conquer, decrease and conquer, and transform and conquer. It includes implementing recursive and non-recursive algorithms to study computational complexity orders from logarithmic to factorial time. Specific algorithms implemented include Strassen's matrix multiplication using divide and conquer approach and topological sorting using decrease and conquer approach. Program code is provided for examples.

Uploaded by

passion job
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 28

Dhanalakshmi Srinivasan

College of Engineering and Technology


ECR, MAMALLAPURAM CHENGALPATTU DISTRICT
Affiliated to Anna University, Chennai.
( Accredited by NAAC with "B++" Grade )

Name:-
Reg.No.:-
Department:-
Semester:-
Subject Name:-
Subject Code:-

Certified that this is the Bonafide record of the


Practical done for the above Subject during a period
is the academic year 20 -20

STAFF IN CHARGE HOD

Submitted for the university Practical Examination held on

Internal Examiner External Examiner


S.NO. Experiment Date Page No.

1 Implement recursive and non-recursive


algorithms and study the order of growth
from log2nto n!.

2 Divide and Conquer - Strassen’s Matrix


Multiplication

3 Decrease and Conquer - Topological Sorting

4 Transform and Conquer - Heap Sort

5 Dynamic programming -
Coinchange Problem, Warshall’s
and Floyd‘s algorithms,Knapsack
Problem

6 Greedy Technique – Dijkstra’s algorithm,


Huffman Trees and codes

7 Iterative improvement - Simplex Method

8 Backtracking – N-Queen problem, Subset Sum


Problem

9 Branch and Bound - Assignment problem,


Traveling Salesman Problem
Ex. 01 : Implement recursive and non-recursive algorithms and study the order of growth from
log2nto n!.

Aim: To study the order of growth from log2(n) to n! and implement algorithms to illustrate
this growth.

Algorithms:
1. Logarithmic Growth - O(log2(n)):
 Recursive Algorithm:
1. If n is less than or equal to 1, return 0.
2. Otherwise, divide n by 2 and add 1 to the result.
3. Repeat step 2 recursively until n becomes 1 or less.
 Non-Recursive Algorithm:
1. Initialize a count to 0.
2. While n is greater than 1, divide n by 2, and increment the count by 1.
3. Return the count as the result.
2. Linear Growth - O(n):
 Recursive Algorithm:
1. If n is less than or equal to 1, return 1.
2. Otherwise, multiply n with the result of the recursive call for n-1.
3. Repeat step 2 recursively until n becomes 1 or less.
 Non-Recursive Algorithm:
1. Initialize a result to 1.
2. For each integer i from 1 to n, multiply the result by i.
3. Return the result as the final answer.
3. Exponential Growth - O(2^n):
 Recursive Algorithm:
1. If n is less than or equal to 1, return 1.
2. Otherwise, multiply 2 with the result of the recursive call for n-1.
3. Repeat step 2 recursively until n becomes 1 or less.
 Non-Recursive Algorithm:
1. Initialize a result to 1.
2. For each integer i from 1 to n, multiply the result by 2.
3. Return the result as the final answer.
4. Factorial Growth - O(n!):
 Recursive Algorithm:
1. If n is 0, return 1.
2. Otherwise, multiply n with the result of the recursive call for n-1.
3. Repeat step 2 recursively until n becomes 0.
 Non-Recursive Algorithm:
1. Initialize a result to 1.
2. For each integer i from 1 to n, multiply the result by i.
3. Return the result as the final answer.

Program:
# Recursive Algorithm for Logarithmic Growth -
O(log2(n)) def log2_recursive(n):
if n <= 1:
return 0
return 1 + log2_recursive(n // 2)
# Non-Recursive Algorithm for Logarithmic Growth -
O(log2(n)) def log2_non_recursive(n):
count = 0
while n > 1:
n //= 2
count += 1
return count
# Recursive Algorithm for Linear Growth -
O(n) def linear_recursive(n):
if n <= 1:
return 1
return n * linear_recursive(n- 1)
# Non-Recursive Algorithm for Linear Growth -
O(n) def linear_non_recursive(n):
result = 1
for i in range(1, n +
1):result *= i
return result
# Recursive Algorithm for Exponential Growth -
O(2^n) def exponential_recursive(n):
if n <= 1:
return 1
return 2 * exponential_recursive(n- 1)
# Non-Recursive Algorithm for Exponential Growth -
O(2^n) def exponential_non_recursive(n):
result = 1
for i in
range(n):
result *= 2
return result
# Recursive Algorithm for Factorial Growth -
O(n!) def factorial_recursive(n):
if n == 0:
return 1
return n * factorial_recursive(n- 1)
# Non-Recursive Algorithm for Factorial Growth -
O(n!) def factorial_non_recursive(n):
result = 1
for i in range(1, n +
1):result *= i
return result
# Example usage:
n = 10 # You can change this value to test different n
values print(f"log2_recursive({n}) = {log2_recursive(n)}")
print(f"log2_non_recursive({n}) =
{log2_non_recursive(n)}") print(f"linear_recursive({n}) =
{linear_recursive(n)}")
print(f"linear_non_recursive({n}) = {linear_non_recursive(n)}")
print(f"exponential_recursive({n}) = {exponential_recursive(n)}")
print(f"exponential_non_recursive({n}) = {exponential_non_recursive(n)}")
print(f"factorial_recursive({n}) = {factorial_recursive(n)}")
print(f"factorial_non_recursive({n}) = {factorial_non_recursive(n)}")

Output:-
log2_recursive(10) = 3
log2_non_recursive(10) = 3
linear_recursive(10) = 3628800
linear_non_recursive(10) = 3628800
exponential_recursive(10) = 1024
exponential_non_recursive(10) = 1024
factorial_recursive(10) = 3628800
factorial_non_recursive(10) = 3628800

Result:
Implementation of recursive and non-recursive algorithms and study the order of growth
from log2n to n! Has been completed successfully.
Ex. 02 Divide and Conquer - Strassen’s Matrix Multiplication

Aim: To implement Strassen’s Matrix Multiplication using the Divide and Conquer approach
and study its efficiency compared to standard matrix multiplication for various matrix sizes.

Algorithms:
1. Input:
 Two square matrices A and B of the same order (n x n).
2. Base Case:
 If the size of the matrices becomes small enough (e.g., n <= a threshold),
perform a standard matrix multiplication algorithm (e.g., the naive approach).
3. Divide:
 Divide matrices A and B into four equal-sized submatrices each. For example,
if A is divided into A11, A12, A21, and A22, then B is divided into B11, B12,
B21, and B22 in the same way.
4. Conquer:
 Recursively compute seven products: P1, P2, P3, P4, P5, P6, and P7.
 P1 = A11 * (B12- B22)
 P2 = (A11 + A12) * B22
 P3 = (A21 + A22) * B11
 P4 = A22 * (B21- B11)
 P5 = (A11 + A22) * (B11 + B22)
 P6 = (A12- A22) * (B21 + B22)
 P7 = (A11- A21) * (B11 + B12)
5. Combine:
 Compute the resulting matrix C using the seven products:
 C11 = P5 + P4- P2 + P6
 C12 = P1 + P2
 C21 = P3 + P4
 C22 = P5 + P1- P3- P7
Program:-
import numpy as np
def strassen_matrix_multiply(A,
B): n = len(A)
# Base case: If matrices are small enough, use standard multiplication
if n <= threshold:
return np.dot(A,
B) # Divide
mid = n // 2
A11, A12 = A[:mid, :mid], A[:mid, mid:]
A21, A22 = A[mid:, :mid], A[mid:, mid:]
B11, B12 = B[:mid, :mid], B[:mid, mid:]
B21, B22 = B[mid:, :mid], B[mid:, mid:]
# Recursively compute the seven products
P1 = strassen_matrix_multiply(A11, B12-
B22) P2 = strassen_matrix_multiply(A11 +
A12, B22) P3 = strassen_matrix_multiply(A21
+ A22, B11) P4 =
strassen_matrix_multiply(A22, B21- B11)
P5 = strassen_matrix_multiply(A11 + A22, B11 +
B22) P6 = strassen_matrix_multiply(A12- A22, B21
+ B22) P7 = strassen_matrix_multiply(A11- A21,
B11 + B12) # Combine to form the result matrix
C11 = P5 + P4- P2 +
P6 C12 = P1 + P2
C21 = P3 + P4
C22 = P5 + P1- P3- P7

# Assemble the result matrix


C = np.vstack((np.hstack((C11, C12)), np.hstack((C21,
C22))) return C
# Set the threshold for the base case (e.g., 2)
threshold = 2
# Example usage:
A = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
B = np.array([[17, 18, 19, 20], [21, 22, 23, 24], [25, 26, 27, 28], [29, 30, 31, 32]])\
result = strassen_matrix_multiply(A, B)
print(result)

Output:-
[[170 180 190 200]
[426 452 478 504]
[682 724 766 808]
[938 996 1054 1112]]

Result:
Implementation of Stassen’s Matrix Multiplication using the Divide and Conquer has been
successfully completed.
Ex.03 Decrease and Conquer - Topological Sorting

Aim:- Implement Decrease and Conquer- Topological Sorting


Algorithm: Topological Sorting
1. Input:
 A Directed Acyclic Graph (DAG).
2. Find a "Source" Node:
 Find a node with no incoming edges (in-degree is 0). If multiple nodes have
no incoming edges, select any.
3. Remove the Node:
 Remove the selected node from the graph along with its outgoing edges.
4. Output:
 Add the removed node to the topological order.
5. Repeat:
 Repeat steps 2-4 until no nodes are left in the graph.
Program:-
from collections import defaultdict
def topological_sort(graph):
def visit(node):
if node not in
visited:
visited.add(node)
for neighbor in graph[node]:
visit(neighbor)
topological_order.append(node)
visited = set()
topological_order =
[] for node in graph:
visit(node)
return topological_order
# Example
usage: graph = {
"A": ["B", "C"],
"B": ["D"],
"C": ["D"],
"D": ["E"],
"E": [],
}
result = topological_sort(graph)
print(result)

Output:-
['A', 'C', 'B', 'D', 'E']

Result:- Implementation of Decrease and Conquer- Topological Sorting


Ex. 04 Transform and Conquer - Heap Sort

Aim:- Implement Heap sort operation

Algorithm: Heap Sort


1. Input:
 An unsorted array.
2. Heapify:
 Transform the array into a max-heap. This involves rearranging
theelements to satisfy the heap property: A[parent] >= A[child].
3. Sort:
 Continuously extract the maximum element from the heap and place it at
the end of the array.
Program :-
def heapify(arr, n, i):
largest = i
left = 2 * i + 1
right = 2 * i +
2
if left < n and arr[left] >
arr[largest]:largest = left
if right < n and arr[right] >
arr[largest]:largest = right
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)
def heap_sort(arr):
n = len(arr)

# Build a max-heap.
for i in range(n // 2- 1,-1,-1):
heapify(arr, n, i)
# Extract elements one by one and place at the end of the array. for
i in range(n- 1, 0,-1):
arr[i], arr[0] = arr[0], arr[i] # Swap
heapify(arr, i, 0)
# Example usage:
arr = [12, 11, 13, 5, 6, 7]
heap_sort(arr)
print(arr)

Output:-
[5, 6, 7, 11, 12, 13]

Result:-
The operation of Heap Sort has been completed successfully
Ex:- 05 Dynamic programming - Coin change Problem, Warshall’s and Floyd‘s algorithms,
Knapsack Problem

1. Coin change Problem

Aim:- Find the minimum number of coins required to make change for a given amount
using a given set of coin denominations.
Algorithm:
 Initialize a list dp of size amount + 1, where dp[i] represents the minimum number
of coins needed to make change for i amount.
 Set dp[0] to 0, as zero coins are needed to make change for 0 amount.
 Iterate through each coin denomination and update dp using the minimum
number of coins for each amount from 1 to amount.
 Return dp[amount] as the minimum number of coins needed, or-1 if change is not
possible.
Program:-
def coin_change(coins, amount):
dp = [float('inf')] * (amount + 1)
dp[0] = 0
for coin in coins:
for i in range(coin, amount + 1):
dp[i] = min(dp[i], dp[i- coin] + 1)
return dp[amount] if dp[amount] != float('inf') else-1
# Example usage:
coins = [1, 2, 5]
amount = 11
result = coin_change(coins, amount)
print(result)

output:- the minimum number of coins needed to make change for 11 is 3 (two 5-coins
and one 1-coin).
2. Warshall's Algorithm:
Aim: Find the transitive closure of a directed graph, determining if there is a path
between every pair of vertices in the graph.
Algorithm:
 Initialize the distance matrix as the adjacency matrix of the graph.
 For each vertex k, consider all pairs of vertices (i, j) and update the distance matrix
with the minimum distance from i to j via vertex k.
 Repeat this process for all vertices k.
 The resulting matrix represents the transitive closure, where dist[i][j] is 1 if there is
a path from vertex i to vertex j, and 0 otherwise.
Program:-
def floyd_warshall(graph):
n = len(graph)
for k in
range(n):
for i in range(n):
for j in range(n):
graph[i][j] = min(graph[i][j], graph[i][k] +
graph[k][j])return graph
# Example usage:
inf = float('inf')
graph = [[0, 3, inf, inf],
[2, 0, inf, inf],
[inf, 7, 0, 1],
[6, inf, inf, 0]]
result =
floyd_warshall(graph)
print(result)

output:-
The resulting matrix represents the shortest path distances between all pairs of vertices in
the graph.
3. Knapsack Problem
Aim: Determine the maximum total value that can be obtained by selecting a subset of
items with weights and values, such that their total weight doesn't exceed a given
knapsack
capacity.
Algorithm:
 Create a 2D table dp of size (n + 1) x (capacity + 1), where dp[i][w] represents the
maximum value that can be obtained using the first i items and a knapsack
capacity of w.
 Fill in the table using dynamic programming, considering the choices of including
or excluding each item.
 The final value in dp at dp[n][capacity] will represent the maximum value that can
be obtained.
Program:-
def knapsack(items, capacity):
n = len(items)
dp = [[0] * (capacity + 1) for _ in range(n +
1)] for i in range(1, n + 1):
for w in range(1, capacity + 1):
weight, value = items[i-
1]if weight <= w:
dp[i][w] = max(dp[i- 1][w], dp[i- 1][w- weight] +
value)else:
dp[i][w] = dp[i-
1][w]return dp[n][capacity]
# Example usage:
items = [(2, 12), (1, 10), (3, 20), (2, 15)]
capacity = 5
result = knapsack(items,
capacity) print(result)

Output:- he maximum total value that can be obtained with a knapsack capacity of 5 is 37
Result:- The operation of Coin change Problem, Warshall’s and Floyd‘s algorithms, Knapsack
Problem has been completed successfully.
Ex.-06 Greedy Technique – Dijkstra’s algorithm, Huffman Trees and codes

1. Dijkstra’s algorithms
Aim: Find the shortest path from a source vertex to all other vertices in a
weighted graph.

Algorithm:
 Start with a distance array, initially set to infinity for all vertices except thesource
vertex, which is set to 0.
 Maintain a set of unvisited vertices.
 While there are unvisited vertices, select the vertex with the smallest distance from the
source.
 Update the distances of its neighbors if a shorter path is found.
 Repeat the process until all vertices have been visited.
Program:-
import heapq
def dijkstra(graph, start):
# Initialize distance to all vertices as infinity distances =
{vertex: float('infinity') for vertex in graph}
distances[start] = 0
priority_queue = [(0, start)]
while priority_queue:
current_distance, current_vertex = heapq.heappop(priority_queue)if
current_distance > distances[current_vertex]:
continue
for neighbor, weight in graph[current_vertex].items():
distance = current_distance + weight
# If a shorter path is found, update the distance and priority queue.if
distance < distances[neighbor]:
distances[neighbor] = distance heapq.heappush(priority_queue,
(distance, neighbor))
return distances
graph = {
'A': {'B': 1, 'C': 4},
'B': {'A': 1, 'C': 2, 'D': 5},
'C': {'A': 4, 'B': 2, 'D': 1},
'D': {'B': 5, 'C': 1}
}
start_vertex = 'A'
result = dijkstra(graph, start_vertex)
print(result)
output:-
{'A': 0, 'B': 1, 'C': 3, 'D': 4}
2. Huffman Trees and Codes:

Aim: Construct an optimal binary tree for encoding and decoding data, where frequentlyused
symbols have shorter codes and less frequently used symbols have longer codes.

Algorithm:
 Create a list of nodes, each representing a symbol and its frequency.
 Build a priority queue (min-heap) using the list of nodes.
 Repeatedly merge the two nodes with the lowest frequencies into a new node,updating
the frequency.
 Continue this process until a single tree is formed.
 Assign binary codes to the tree's edges, where left edges are assigned '0' and rightedges '1'.
Program:-
import heapq
from collections import defaultdict def
build_huffman_tree(symbols):.
heap = [(freq, [sym, ""]) for sym, freq in symbols.items()]
heapq.heapify(heap)
while len(heap) > 1:
# Remove the two nodes with the lowest frequencies.freq1,
node1 = heapq.heappop(heap)
freq2, node2 = heapq.heappop(heap)
merged_freq = freq1 + freq2
merged_node = [node1, node2]
heapq.heappush(heap, (merged_freq, merged_node))def
generate_huffman_codes(tree, prefix="", codes=None):
if codes is None:
codes = {}
if len(tree) == 1:
symbol, _ = tree[0]
codes[symbol] = prefix
else:
left, right = tree
generate_huffman_codes(left, prefix + "0", codes)
generate_huffman_codes(right, prefix + "1", codes)
return codes
# Example usage:
symbols = {'A': 5, 'B': 9, 'C': 12, 'D': 13, 'E': 16, 'F': 45}
huffman_tree = build_huffman_tree(symbols) huffman_codes =
generate_huffman_codes(huffman_tree)print(huffman_codes)
Output:-
{'A': '1100', 'B': '1101', 'C': '100', 'D': '101', 'E': '111', 'F': '0'}

Result:-
Implementation of Dijkstra’s algorithm, Huffman Trees and codes has been completed
successfully.
Ex. 07 Iterative improvement - Simplex Method

Aim: Solve linear programming problems to optimize a linear objective function subjectto linear
equality and inequality constraints.
Algorithm:
1. Start with an initial feasible solution. This is typically achieved by introducing slack or
surplus variables.
2. While there exists a pivot element in the current tableau (indicating that the current solution
isn't optimal): a. Select a pivot column (usually the one with the most negative coefficient in
the objective function). b. Select a pivot row (the one with thesmallest non-negative ratio
between the right-hand side and the pivot column's coefficients). c. Update the tableau by
applying the pivot operation, which involves making the pivot element 1 and updating the
other elements in the pivot column androw. d. Repeat steps (a) to (c) until no more pivot
elements can be found.
3. The final tableau represents the optimal solution to the linear programming problem.Extract
the optimal values of decision variables from the tableau.
Program:-
from scipy.optimize import linprog
# Define the coefficients of the objective function.c =
[-3, -2]
# Define the coefficients of the inequality constraints.A = [
[1, 1],
[2, 1]
]
# Define the right-hand side of the inequality constraints.b =
[4, 5]
# Define the bounds for decision variables (default is non-negative).
x_bounds = (0, None)
y_bounds = (0, None)
# Use SciPy's linprog to solve the linear programming problem. result =
linprog(c, A_ub=A, b_ub=b, bounds=[x_bounds, y_bounds])
print("Optimal Solution:")
print("x =", result.x[0])
print("y =", result.x[1])
print("Optimal Value of Objective Function:", -result.fun)
Output:-
Optimal Solution:
x = 1.0
y = 3.0
Optimal Value of Objective Function: 7.0

Result:- Implementation of Simplex Method has been completed Successfully


Ex.08 Backtracking – N-Queen problem, Subset Sum Problem

1. N-Queens Problem:
Aim: Place N chess queens on an N×N chessboard so that no two queens threateneach other.
Algorithm:
1. Start in the leftmost column.
2. If all queens are placed, return true.
3. Try all rows in the current column. For each row, do the following: a. If the queen canbe
placed safely in this row and column, mark this cell and recursively check the nextcolumn. b.
If the recursive call returns true, return true. c. If placing the queen in this row and column
leads to a solution, return true.
4. If no row can be safely placed, return false to trigger backtracking.
Program:-
def is_safe(board, row, col, n):
# Check if there is a queen in the current row to the leftfor i
in range(col):
if board[row][i] == 1:
return False
for i, j in zip(range(row, -1, -1), range(col, -1, -1)):if
board[i][j] == 1:
return False
for i, j in zip(range(row, n, 1), range(col, -1, -1)):if
board[i][j] == 1:
return False
return True
def solve_n_queens(n):
board = [[0] * n for _ in range(n)]
if not solve_n_queens_util(board, 0, n):
return "No solution exists."
return board
def solve_n_queens_util(board, col, n):if
col >= n:
return True
for i in range(n):
if is_safe(board, i, col, n):
board[i][col] = 1
if solve_n_queens_util(board, col + 1, n):
return True
board[i][col] = 0
return False
Outpur:-
[0, 1, 0, 0]
[0, 0, 0, 1]
[1, 0, 0, 0]
[0, 0, 1, 0]

2. Subset Sum Problem:


Aim: Find a subset of a given set of positive integers such that their sum is equal to agiven
positive integer.
Algorithm:
1. Start with the last element of the set.
2. Include the last element in the current subset and recursively check if a subset sumexists.
3. Exclude the last element from the current subset and recursively check if a subsetsum
exists.
4. If a subset sum is found, return true.
5. If no subset sum is found, return false.
Program:-
def is_subset_sum(arr, n, target_sum):if
target_sum == 0:
return True
if n == 0 and target_sum != 0:
return False
if arr[n - 1] > target_sum:
return is_subset_sum(arr, n - 1, target_sum)
return is_subset_sum(arr, n - 1, target_sum) or is_subset_sum(arr, n - 1, target_sum -arr[n - 1])
# Example usage:
arr = [3, 34, 4, 12, 5, 2]
target_sum = 9n
= len(arr)
result = is_subset_sum(arr, n, target_sum)print(result)
Output:-
True

Result:-
Implementation of N-Queen problem, Subset Sum Problem has been completed
Successfully .
Ex. 09 Branch and Bound - Assignment problem, Traveling Salesman Problem

Branch and Bound - Assignment problem, Traveling Salesman Proble


1.Assignment Problem:
Aim: Assign n tasks to n workers, minimizing the total cost while ensuring that each taskis
assigned to exactly one worker and each worker is assigned to exactly one task.
Algorithm:
1. Start with an initial solution (can be all zeros).
2. Calculate the lower bound on the total cost of the current solution.
3. Create subproblems by relaxing constraints. Duplicate the current problem intomultiple
subproblems by assigning tasks to workers or eliminating certain assignments.
4. Solve each subproblem to find the lower bound on its cost.
5. If the lower bound of a subproblem is greater than or equal to the best solution foundso far,
prune that branch.
6. If a feasible solution is found in a subproblem, update the best solution if it's betterthan the
current best solution.
7. Continue the process until all subproblems are explored.
Program:-
import numpy as np
import munkres
def assignment_problem(cost_matrix):m
= munkres.Munkres()
indexes = m.compute(cost_matrix)
total_cost = sum(cost_matrix[i][j] for i, j in indexes)
return indexes, total_cost
# Example usage:
cost_matrix = np.array([[90, 76, 75, 80],
[35, 85, 55, 65],
[125, 95, 90, 105],
[45, 110, 95, 115]])
indexes, total_cost = assignment_problem(cost_matrix)
print("Indexes:", indexes)
print("Total Cost:", total_cost)
Output:-
Indexes: [(0, 2), (1, 0), (2, 3), (3, 1)]
Total Cost: 265

2.Traveling Salesman Problem:


Aim: Find the shortest possible route that visits a given set of cities and returns to theorigin city.
Algorithm:
1. Start with an initial solution (can be a trivial solution or a relaxed solution).
2. Calculate the lower bound on the total distance of the current solution.
3. Create subproblems by relaxing constraints. Duplicate the current problem intomultiple
subproblems by exploring different orders of visiting cities.
4. Solve each subproblem to find the lower bound on its distance.
5. If the lower bound of a subproblem is greater than or equal to the best solution foundso far,
prune that branch.
6. If a feasible solution is found in a subproblem, update the best solution if it's betterthan the
current best solution.
7. Continue the process until all subproblems are explored.
Program:-
import numpy as np
import sys
def traveling_salesman_problem(graph):def
tsp_dp(mask, pos):
if mask == (1 << n) - 1:
return graph[pos][0]
if dp[mask][pos] != -1:
return dp[mask][pos]
min_dist = sys.maxsize
for city in range(n):
if (mask >> city) & 1 == 0:
new_mask = mask | (1 << city)
new_dist = graph[pos][city] + tsp_dp(new_mask, city)
min_dist = min(min_dist, new_dist)
dp[mask][pos] = min_dist
return min_dist
n = len(graph)
dp = [[-1] * n for _ in range(1 << n)]
mask = 1 # Start with the first city
min_distance = tsp_dp(mask, 0) return
min_distance
# Example usage:
graph = np.array([
[0, 29, 20, 21],
[29, 0, 15, 17],
[20, 15, 0, 28],
[21, 17, 28, 0]
])
min_distance = traveling_salesman_problem(graph)
print("Minimum Distance:", min_distance)

Output:-
Minimum Distance: 85

Result:-
Implementation of Assignment problem, Traveling Salesman ProbleHas
been completed successfully.
.

You might also like