0% found this document useful (0 votes)
9 views60 pages

Python Algorithms: Factorial, Fibonacci, Matrix Multiplication

Uploaded by

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

Python Algorithms: Factorial, Fibonacci, Matrix Multiplication

Uploaded by

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

[Link].

1(A) IMPLEMENTATION OF RECURSIVE ALGORITHM – FACTORIAL

CALCULATION

AIM

To implement a recursive algorithm in Python for calculating the factorial of a given


number.

ALGORITHM

Step 1: Start the program.


Step 2: Define a function factorial(n) that takes an integer n as input.
Step 3: Check if n is 0 or 1. if yes, return 1.
Step 4: Otherwise, return n * factorial(n - 1) .
Step 5: Get input from the user for the number n.
Step 6: Call the factorial(n) function and store the result.
Step 7: Display the factorial of the given number.
Step 8: Stop the program.
PROGRAM

def factorial(n):

if n == 0 or n == 1:

return 1

else:

return n * factorial(n - 1)

num = int(input("Enter a number: "))

if num < 0:

print("Factorial is not defined for negative numbers.")

else:

result = factorial(num)

print("Factorial of", num, "is:", result)


OUTPUT

Enter a non-negative integer: 5

Factorial of 5 is 120

RESULT

Thus, the recursive algorithm for factorial calculation was successfully implemented and
executed in Python.
[Link].1(B) IMPLEMENTATION OF NON-RECURSIVE ALGORITHM

AIM

To implement a non-recursive algorithm in Python to generate the Fibonacci sequence up


to a given number of terms

ALGORITHM

Step 1: Read the number of terms n from the user.

Step 2: Initialize the first two terms as a = 0 and b = 1.

Step 3: Use a loop to print each term and update a and b as:

a, b = b, a + b

Step 4: Repeat until all terms are printed.


PROGRAM

# Non-recursive Fibonacci sequence

n_terms = int(input("Enter number of terms: "))

if n_terms<= 0:

print("Please enter a positive integer.")

else:

a, b = 0, 1

print("Fibonacci sequence:")

for _ in range(n_terms):

print(a, end=" ")

a, b = b, a + b
OUTPUT

Enter number of terms: 7

Fibonacci sequence:

0112358

RESULT

Thus, the program successfully generates the Fibonacci sequence up to the given number
of terms using a non-recursive algorithm.
[Link].2 DIVIDE AND CONQUER – STRASSEN’S MATRIX MULTIPLICATION

AIM

To implement Strassen’s Matrix Multiplication algorithm using the divide and conquer
approach in Python.

ALGORITHM

Step 1: Start the program.


Step 2: Read two square matrices (of order 2×2 for simplicity).
Step 3: Divide each matrix into four submatrices (A11, A12, A21, A22 and B11, B12, B21, B22).
Step 4: Compute the following seven products recursively:
P1 = (A11 + A22) × (B11 + B22)
P2 = (A21 + A22) × B11
P3 = A11 × (B12 − B22)
P4 = A22 × (B21 − B11)
P5 = (A11 + A12) × B22
P6 = (A21 − A11) × (B11 + B12)
P7 = (A12 − A22) × (B21 + B22)
Step 5: Compute the final submatrices of result matrix C as:
C11 = P1 + P4 − P5 + P7
C12 = P3 + P5
C21 = P2 + P4
C22 = P1 − P2 + P3 + P6
Step 6: Combine the submatrices to get the final matrix C.
Step 7: Display the result.
Step 8: Stop the program.
PROGRAM

def strassen(a, b):


# Base case for 2x2 matrices
if len(a) == 1:
return [[a[0][0] * b[0][0]]]

# Splitting matrices into quarters


n = len(a)
mid = n // 2

a11 = [[a[i][j] for j in range(mid)] for i in range(mid)]


a12 = [[a[i][j] for j in range(mid, n)] for i in range(mid)]
a21 = [[a[i][j] for j in range(mid)] for i in range(mid, n)]
a22 = [[a[i][j] for j in range(mid, n)] for i in range(mid, n)]

b11 = [[b[i][j] for j in range(mid)] for i in range(mid)]


b12 = [[b[i][j] for j in range(mid, n)] for i in range(mid)]
b21 = [[b[i][j] for j in range(mid)] for i in range(mid, n)]
b22 = [[b[i][j] for j in range(mid, n)] for i in range(mid, n)]

# Calculating p1 to p7 using Strassen’s formula


p1 = strassen(add(a11, a22), add(b11, b22))
p2 = strassen(add(a21, a22), b11)
p3 = strassen(a11, sub(b12, b22))
p4 = strassen(a22, sub(b21, b11))
p5 = strassen(add(a11, a12), b22)
p6 = strassen(sub(a21, a11), add(b11, b12))
p7 = strassen(sub(a12, a22), add(b21, b22))

# Combining results into a single matrix


c11 = add(sub(add(p1, p4), p5), p7)
c12 = add(p3, p5)
c21 = add(p2, p4)
c22 = add(sub(add(p1, p3), p2), p6)

# Joining the four submatrices into one


new_matrix = []
for i in range(mid):
new_matrix.append(c11[i] + c12[i])
for i in range(mid):
new_matrix.append(c21[i] + c22[i])
return new_matrix

# Helper functions
def add(x, y):
n = len(x)
return [[x[i][j] + y[i][j] for j in range(n)] for i in range(n)]

def sub(x, y):


n = len(x)
return [[x[i][j] - y[i][j] for j in range(n)] for i in range(n)]
# Main program
a = [[1, 2], [3, 4]]
b = [[5, 6], [7, 8]]
print("Matrix A:", a)
print("Matrix B:", b)
result = strassen(a, b)
print("Resultant Matrix after Strassen's Multiplication:")
for row in result:
print(row)
OUTPUT

Matrix A: [[1, 2], [3, 4]]

Matrix B: [[5, 6], [7, 8]]

Resultant Matrix after Strassen's Multiplication:

[19, 22]

[43, 50]
RESULT

Thus, the Strassen’s Matrix Multiplication algorithm was successfully implemented using
the divide and conquer approach in Python.
[Link].3 DECREASE AND CONQUER – TOPOLOGICAL SORT

AIM

To perform topological sorting of a Directed Acyclic Graph (DAG) using depth-first


search (DFS) in the decrease and conquer approach.

ALGORITHM

1. Input the number of vertices and edges.

2. Store the graph as an adjacency list.

3. Maintain a visited array to mark visited nodes.

4. For each unvisited vertex, call DFS:

o Mark the vertex as visited.

o Recursively call DFS for all unvisited neighbors.

o Push the vertex to a stack after visiting all neighbors.

5. Reverse the stack to get the topological order.

6. Display the order.


PROGRAM
def dfs(v, visited, graph, stack):

visited[v] = True

for neighbor in graph[v]:

if not visited[neighbor]:

dfs(neighbor, visited, graph, stack)

[Link](v)

def topological_sort(n, edges):

graph = [[] for _ in range(n)]

for u, v in edges:

graph[u].append(v)

visited = [False] * n

stack = []

for i in range(n):

if not visited[i]:

dfs(i, visited, graph, stack)

return stack[::-1] # reverse stack for topo order

# Example usage

n=6

edges = [(5, 2), (5, 0), (4, 0), (4, 1), (2, 3), (3, 1)]

print("Topological Order:", topological_sort(n, edges))


OUTPUT

Topological Order: [5, 4, 2, 3, 1, 0]

RESULT

Thus, the Topological Sort using the DFS method was successfully implemented
using the Decrease and Conquer strategy in Python.
[Link].4 TRANSFORM AND CONQUER – HEAP SORT

AIM

To sort an array using Heap Sort, which transforms the array into a heap and then extracts
elements in sorted order.

ALGORITHM

1. Build a max heap from the input array.

2. Repeat until the heap size is 1:

o Swap the root (largest) with the last element.

o Reduce heap size by 1.

o Heapify the root to maintain the max heap property.

3. The array is now sorted in ascending order.


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 max heap

for i in range(n // 2 - 1, -1, -1):

heapify(arr, n, i)

# Extract elements from heap

for i in range(n - 1, 0, -1):

arr[0], arr[i] = arr[i], arr[0]

heapify(arr, i, 0)

arr = [12, 11, 13, 5, 6, 7]

heap_sort(arr)

print("Sorted array:", arr)


OUTPUT

Sorted array: [5, 6, 7, 11, 12, 13]

RESULT

Thus, the Heap Sort algorithm was successfully implemented using the Transform and Conquer
approach in Python.
[Link].5(A) DYNAMIC PROGRAMMING – COIN CHANGE PROBLEM

AIM

To find the minimum number of coins required to make a given amount using dynamic
programming.

ALGORITHM

1. Input the coin denominations and the target amount.

2. Create a DP array of size amount + 1 initialized to infinity (or a large number), except
dp[0] = 0.

3. For each coin, update the DP array:

o For i from coin value to amount:

 dp[i] = min(dp[i], dp[i - coin] + 1)

4. If dp[amount] is infinity, return -1 (no solution).

5. Else, return dp[amount].


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

coins = [1, 2, 5]

amount = 11

result = coin_change(coins, amount)

print("Minimum coins required:", result)


OUTPUT

Minimum coins required: 3

RESULT

Thus,the program successfully computes the minimum number of coins required to make
the given amount using Dynamic Programming.
[Link].5(B) DYNAMIC PROGRAMMING- WARSHALL’S ALGORITHM AND FLOYD’S

ALGORITHM

AIM

To implement Warshall’s Algorithm (for transitive closure) and Floyd’s Algorithm (for
shortest path) using Dynamic Programming in Python.

ALGORITHM

A. Warshall’s Algorithm

Step 1: Start the program.


Step 2: Input the adjacency matrix of the graph.
Step 3: For each vertex k, update path[i][j] = path[i][j] or (path[i][k] and path[k][j]).
Step 4: After all iterations, path[i][j] will show if there is a path from vertex i to j.
Step 5: Display the final transitive closure matrix.

B. Floyd’s Algorithm

Step 1: Start the program.


Step 2: Input the weighted adjacency matrix of the graph.
Step 3: For each vertex k, update
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]).
Step 4: After all iterations, dist[i][j] contains the shortest distance from i to j.
Step 5: Display the result matrix.
PROGRAM

def warshall(matrix):
n = len(matrix)
reach = [row[:] for row in matrix] # copy matrix
for k in range(n):
for i in range(n):
for j in range(n):
reach[i][j] = reach[i][j] or (reach[i][k] and reach[k][j])
return reach
# ---------- Floyd’s Algorithm ----------
def floyd(matrix):
n = len(matrix)
dist = [row[:] for row in matrix] # copy matrix
for k in range(n):
for i in range(n):
for j in range(n):
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
return dist
# ---------- Main Program ----------
INF = 9999
adj_warshall = [
[1, 1, 0],
[0, 1, 1],
[0, 0, 1]
]

adj_floyd = [
[0, 4, INF],
[INF, 0, 2],
[1, INF, 0]
]
print("Original Matrix for Warshall’s Algorithm:")
for row in adj_warshall:
print(row)

print("\nTransitive Closure (Warshall’s Algorithm):")


result1 = warshall(adj_warshall)
for row in result1:
print(row)

print("\nOriginal Matrix for Floyd’s Algorithm:")


for row in adj_floyd:
print(row)

print("\nAll-Pairs Shortest Path (Floyd’s Algorithm):")


result2 = floyd(adj_floyd)
for row in result2:
print(row)
OUTPUT

Original Matrix for Warshall’s Algorithm:

[1, 1, 0]

[0, 1, 1]

[0, 0, 1]

Transitive Closure (Warshall’s Algorithm):

[1, 1, 1]

[0, 1, 1]

[0, 0, 1]

Original Matrix for Floyd’s Algorithm:

[0, 4, 9999]

[9999, 0, 2]

[1, 9999, 0]

All-Pairs Shortest Path (Floyd’s Algorithm):

[0, 4, 6]

[3, 0, 2]

[1, 5, 0]
RESULT

Thus, the Warshall’s Algorithm and Floyd’s Algorithm were successfully implemented
using the Dynamic Programming approach in Python
[Link].5(C) DYNAMIC PROGRAMMING - KNAPSACK PROBLEM

AIM

To implement the 0/1 Knapsack Problem using Dynamic Programming in Python to


find the maximum profit for a given weight capacity.

ALGORITHM

Step 1: Start the program.


Step 2: Input the number of items n, weights array wt[], values array val[], and maximum
capacity W.
Step 3: Create a 2D array dp[n+1][W+1] where dp[i][w] stores maximum value for first i items
and weight w.
Step 4: Initialize dp[0][w] = 0 for all w (0 items) and dp[i][0] = 0 for all i (0 capacity).
Step 5: Fill the dp table using:
If wt[i-1] <= w:
dp[i][w] = max(val[i-1] + dp[i-1][w - wt[i-1]], dp[i-1][w])
Else:
dp[i][w] = dp[i-1][w]
Step 6: The maximum profit is dp[n][W].
Step 7: Display the result.
Step 8: Stop the program.
PROGRAM

def knapsack(val, wt, W):

n = len(val)

dp = [[0 for _ in range(W+1)] for _ in range(n+1)]

for i in range(1, n+1):

for w in range(1, W+1):

if wt[i-1] <= w:

dp[i][w] = max(val[i-1] + dp[i-1][w - wt[i-1]], dp[i-1][w])

else:

dp[i][w] = dp[i-1][w]

return dp[n][W]

# Main Program

val = [60, 100, 120]

wt = [10, 20, 30]

W = 50

print("Values:", val)

print("Weights:", wt)

print("Maximum Capacity:", W)

max_profit = knapsack(val, wt, W)

print("Maximum Profit:", max_profit)


OUTPUT

Values: [60, 100, 120]

Weights: [10, 20, 30]

Maximum Capacity: 50

Maximum Profit: 220

RESULT

Thus, the 0/1 Knapsack Problem was successfully implemented using Dynamic
Programming, and the maximum profit for the given weight capacity was obtained.
[Link].6(A) GREEDY TECHNIQUE - DIJKSTRA’S ALGORITHM

AIM

To implement Dijkstra’s Algorithm using the Greedy technique in Python to find the
shortest path from a source vertex to all other vertices in a weighted graph.

ALGORITHM

Step 1: Start the program.


Step 2: Input the number of vertices V and the adjacency matrix of the graph.
Step 3: Initialize dist[] array to store the shortest distance from the source (set all distances to ∞
except the source, which is 0).
Step 4: Initialize a visited[] array to track vertices whose shortest distance is finalized.
Step 5: Repeat V times:
• Pick the unvisited vertex u with the minimum distance.
• Mark u as visited.
• For all neighbors v of u, if v is unvisited and dist[u] + weight(u, v) <dist[v], update dist[v].
Step 6: After all iterations, dist[] contains shortest distances from the source.
Step 7: Display the result.
Step 8: Stop the program.
PROGRAM

def dijkstra(graph, src):

V = len(graph)

dist = [float('inf')] * V

dist[src] = 0

visited = [False] * V

for _ in range(V):

# Pick the vertex with minimum distance

u = min((d for d in range(V) if not visited[d]), key=lambda x: dist[x])

visited[u] = True

# Update distances of adjacent vertices

for v in range(V):

if graph[u][v] > 0 and not visited[v] and dist[u] + graph[u][v] <dist[v]:

dist[v] = dist[u] + graph[u][v]

return dist

graph = [

[0, 4, 0, 0, 0, 0, 0, 8, 0],

[4, 0, 8, 0, 0, 0, 0, 11, 0],

[0, 8, 0, 7, 0, 4, 0, 0, 2],

[0, 0, 7, 0, 9, 14, 0, 0, 0],

[0, 0, 0, 9, 0, 10, 0, 0, 0],

[0, 0, 4, 14, 10, 0, 2, 0, 0],


[0, 0, 0, 0, 0, 2, 0, 1, 6],

[8, 11, 0, 0, 0, 0, 1, 0, 7],

[0, 0, 2, 0, 0, 0, 6, 7, 0]

source = 0

distances = dijkstra(graph, source)

print("Shortest distances from vertex", source, "to all other vertices:")

for i, d in enumerate(distances):

print(f"Vertex {i}: {d}")


OUTPUT

Shortest distances from vertex 0 to all other vertices:

Vertex 0: 0

Vertex 1: 4

Vertex 2: 12

Vertex 3: 19

Vertex 4: 21

Vertex 5: 11

Vertex 6: 9

Vertex 7: 8

Vertex 8: 14
RESULT

Thus, the Dijkstra’s Algorithm was successfully implemented using the Greedy technique
in Python to find the shortest distances from a source vertex to all other vertices.
[Link].6(B) GREEDY TECHNIQUE – HUFFMAN TREES AND CODES

AIM

To implement Huffman Coding using the Greedy technique in Python to generate prefix-
free binary codes for characters based on their frequencies.

ALGORITHM

Step 1: Start the program.


Step 2: Input the set of characters and their frequencies.
Step 3: Create a priority queue (min-heap) of nodes, each node containing a character and its
frequency.
Step 4: Repeat until only one node remains in the queue:
• Extract two nodes with the smallest frequencies.
• Create a new internal node with frequency equal to the sum of the two nodes.
• Set the two extracted nodes as the left and right children of the new node.
• Insert the new node back into the priority queue.
Step 5: The remaining node is the root of the Huffman Tree.
Step 6: Traverse the tree to assign binary codes:
• Go left → append 0, go right → append 1.
Step 7: Display the Huffman codes for all characters.
Step 8: Stop the program.
PROGRAM

import heapq

class Node:

def __init__(self, char, freq):

[Link] = char

[Link] = freq

[Link] = None

[Link] = None

# Define comparators for priority queue

def __lt__(self, other):

return [Link]<[Link]

def huffman_codes(char_freq):

heap = [Node(char, freq) for char, freq in char_freq.items()]

[Link](heap)

while len(heap) > 1:

left = [Link](heap)

right = [Link](heap)

merged = Node(None, [Link] + [Link])

[Link] = left

[Link] = right

[Link](heap, merged)

root = heap[0]

codes = {}

def assign_codes(node, code):

if node is None:
return

if [Link] is not None:

codes[[Link]] = code

assign_codes([Link], code + "0")

assign_codes([Link], code + "1")

assign_codes(root, "")

return codes

# Main Program

char_freq = {'A': 5, 'B': 9, 'C': 12, 'D': 13, 'E': 16, 'F': 45}

codes = huffman_codes(char_freq)

print("Character Frequencies:", char_freq)

print("\nHuffman Codes:")

for char, code in [Link]():

print(f"{char}: {code}")
OUTPUT

Character Frequencies: {'A': 5, 'B': 9, 'C': 12, 'D': 13, 'E': 16, 'F': 45}

Huffman Codes:

F: 0

C: 100

D: 101

A: 1100

B: 1101

E: 111
RESULT

Thus, the Huffman Coding was successfully implemented using the Greedy technique
[Link] ITERATIVEIMPROVEMENT – SIMPLEX METHOD

AIM

To implement the Simplex Method using Iterative Improvement in Python to solve a


linear programming problem (maximize or minimize objective function).

ALGORITHM

Step 1: Convert inequalities into equalities by adding slack variables.

Step 2: Set up the initial simplex tableau.

Step 3: Identify the pivot column (most negative value in bottom row → entering variable).

Step 4: Identify the pivot row using the minimum positive ratio test (b / pivot column element).

Step 5: Perform pivot operations to make pivot element = 1 and other column entries = 0.

Step 6: Repeat Steps 3–5 until there are no negative values in the bottom row.

Step 7: Read off the optimal solution and maximum Z.


PROGRAM

import numpy as np

def simplex(c, A, b):

n = len(c)

m = len(b)

# Step 1: Create initial tableau

tableau = [Link]((m + 1, n + m + 1))

tableau[:m, :n] = A

tableau[:m, n:n + m] = [Link](m) # slack variables

tableau[:m, -1] = b

tableau[-1, :n] = -c # objective function

while True:

# Step 2: Check for optimality

if all(tableau[-1, :-1] >= 0):

break # optimal reached

# Step 3: Entering variable (most negative coefficient)

pivot_col = [Link](tableau[-1, :-1])

# Step 4: Leaving variable (min ratio test)

ratios = []

for i in range(m):

if tableau[i, pivot_col] > 0:

[Link](tableau[i, -1] / tableau[i, pivot_col])

else:

[Link]([Link])

pivot_row = [Link](ratios)
# Step 5: Pivot operation

pivot = tableau[pivot_row, pivot_col]

tableau[pivot_row, :] /= pivot

for i in range(m + 1):

if i != pivot_row:

tableau[i, :] -= tableau[i, pivot_col] * tableau[pivot_row, :]

# Step 6: Extract results

solution = [Link](n)

for i in range(m):

col = tableau[i, :n]

if list(col).count(1) == 1 and list(col).count(0) == n - 1:

j = [Link](col == 1)[0][0]

solution[j] = tableau[i, -1]

Z = tableau[-1, -1]

return solution, Z, tableau

# Example usage:

c = [Link]([3, 2]) # Coefficients of objective function

A = [Link]([[1, 1], [1, 2]]) # Coefficients of constraints

b = [Link]([4, 6]) # RHS of constraints

solution, Z, tableau = simplex(c, A, b)

print("Optimal solution (x):", solution)

print("Maximum Z value:", Z)

print("\nFinal Tableau:\n", tableau)


OUTPUT

Optimal solution (x): [0. 2.]

Maximum Z value: 12.0

Final Tableau:

[[ 1. 1. 1. 0. 4.]

[ 0. 1. -1. 1. 2.]

[ 0. 1. 3. 0. 12.]]

RESULT

Thus, the Simplex Method using Iterative Improvement was implemented successfully.
[Link](A) BACKTRACKING–NQUEENPROBLEM

AIM

To solve the N-Queen problem using the backtracking algorithm, where we must place N
queens on an N×N chessboard such that no two queens attack each other (i.e., no two queens
share the same row, column, or diagonal).

ALGORITHM

1. Start with an empty chessboard.

2. Place a queen in the first column of the first row.

3. Check if placing a queen is safe (no other queen attacks this position).

4. If it’s safe, place the queen and move to the next row.

5. If it’s not safe, try the next column in the current row.

6. If all columns in a row lead to conflicts, backtrack to the previous row and move the
queen to the next column.

7. Repeat until:

o All N queens are placed safely → solution found, or

o No position is possible → no solution exists.

8. Display the board configuration(s).


PROGRAM

def print_board(board):

for row in board:

print(" ".join(row))

print()

def is_safe(board, row, col, n):

# Check column

for i in range(row):

if board[i][col] == 'Q':

return False

# Check upper-left diagonal

i, j = row - 1, col - 1

while i >= 0 and j >= 0:

if board[i][j] == 'Q':

return False

i -= 1

j -= 1

# Check upper-right diagonal

i, j = row - 1, col + 1

while i >= 0 and j < n:

if board[i][j] == 'Q':

return False

i -= 1

j += 1

return True
def solve_n_queens(board, row, n):

if row == n:

print_board(board)

return True

res = False

for col in range(n):

if is_safe(board, row, col, n):

board[row][col] = 'Q'

res = solve_n_queens(board, row + 1, n) or res

board[row][col] = '.' # Backtrack

return res

def n_queen(n):

board = [['.' for _ in range(n)] for _ in range(n)]

if not solve_n_queens(board, 0, n):

print("No solution exists for", n, "Queens")

# Example usage:

n=4

n_queen(n)
OUTPUT

.Q..

...Q

Q...

..Q.

..Q.

Q...

...Q

.Q..

RESULT

Thus, the N-Queen problem was successfully solved using the Backtracking technique.
[Link](B) BACKTRACKING – SUBSET SUM PROBLEM

AIM

To write a Python program to solve the Subset Sum Problem using the backtracking
algorithm.

ALGORITHM

1. Start.

2. Input the number of elements in the set and the required target sum.

3. Generate all possible subsets using backtracking.

4. For each element:

o Include the element in the subset and recursively check the next element.

o Exclude the element and recursively check the next element.

5. If the current subset’s sum equals the target sum, display the subset.

6. If all elements are processed, backtrack to explore other possibilities.

7. Stop.
PROGRAM

def subset_sum(nums, target, partial=[]):

s = sum(partial)

# Check if the current subset sums to target

if s == target:

print("Subset:", partial)

if s >= target:

return # Stop if the sum exceeds target

for i in range(len(nums)):

n = nums[i]

remaining = nums[i+1:]

subset_sum(remaining, target, partial + [n])

# Main Program

nums = [3, 4, 5, 2]

target = 7

print("Given set:", nums)

print("Target sum:", target)

print("Subsets that sum to target are:")

subset_sum(nums, target)
OUTPUT

Given set: [3, 4, 5, 2]

Target sum: 7

Subsets that sum to target are:

Subset: [3, 4]

Subset: [5, 2]
RESULT

Thus, the Subset Sum Problem was successfully implemented using the Backtracking
algorithm, and all subsets whose sum equals the target value were displayed.
[Link]: 9(A) BRANCH AND BOUND – ASSIGNMENT PROBLEM

AIM

To write a Python program to solve the Assignment Problem using the Branch and Bound
algorithm.

ALGORITHM

1. Start.

2. Represent the problem as an n × n cost matrix.

3. Create a state-space tree where each level represents a worker.

4. At each node, assign the worker to one of the unassigned jobs.

5. Compute a cost bound (lower bound) for each node:

o Add the cost of the current assignment.

o Add the minimum possible cost from the remaining unassigned workers.

6. Use a priority queue to explore the node with the least cost bound first.

7. When all workers are assigned, record the total cost.

8. The node leading to the minimum total cost gives the optimal assignment.

9. Stop.
PROGRAM

from itertools import permutations

def assignment_problem(cost):

n = len(cost)

jobs = [i for i in range(n)]

min_cost = float('inf')

best_perm = None

# Try all possible job assignments (permutations)

for perm in permutations(jobs):

total = 0

for i in range(n):

total += cost[i][perm[i]]

if total <min_cost:

min_cost = total

best_perm = perm

print("Best Assignment:", best_perm)

print("Minimum Cost:", min_cost)

# Main Program
cost = [

[9, 2, 7, 8],

[6, 4, 3, 7],

[5, 8, 1, 8],

[7, 6, 9, 4]

print("Cost Matrix:")

for row in cost:

print(row)

assignment_problem(cost)
OUTPUT

Cost Matrix:

[9, 2, 7, 8]

[6, 4, 3, 7]

[5, 8, 1, 8]

[7, 6, 9, 4]

Best Assignment: (1, 0, 2, 3)

Minimum Cost: 13
RESULT

Thus, the Assignment Problem was successfully solved using the Branch and Bound
approach
[Link](B) BRANCH AND BOUND – TRAVELLING SALESMAN \

PROBLEM

AIM

To write a Python program to solve the Travelling Salesman Problem (TSP) using the
Branch and Bound technique.

ALGORITHM

1. Start.

2. Represent the travel costs between cities using a cost matrix.

3. Select a city as the starting point.

4. Generate all possible paths that visit each city exactly once.

5. For each path, calculate the total cost (including returning to the start).

6. Keep track of the minimum total cost and the corresponding route.

7. Display the shortest path and minimum cost.

8. Stop.
PROGRAM

from itertools import permutations

def travelling_salesman(cost):

n = len(cost)

cities = [i for i in range(n)]

min_cost = float('inf')

best_path = []

# Try all possible routes starting from city 0

for perm in permutations(cities[1:]):

current_cost = 0

path = [0] + list(perm) + [0] # start and end at city 0

# Calculate total cost of this route

for i in range(len(path) - 1):

current_cost += cost[path[i]][path[i + 1]]

# Update minimum cost and path

if current_cost<min_cost:

min_cost = current_cost

best_path = path

print("Shortest Path:", " → ".join(str(c) for c in best_path))

print("Minimum Cost:", min_cost)


# Main Program

cost = [

[0, 10, 15, 20],

[10, 0, 35, 25],

[15, 35, 0, 30],

[20, 25, 30, 0]

print("Cost Matrix:")

for row in cost:

print(row)

travelling_salesman(cost)
OUTPUT

Cost Matrix:

[0, 10, 15, 20]

[10, 0, 35, 25]

[15, 35, 0, 30]

[20, 25, 30, 0]

Shortest Path: 0 → 1 → 3 → 2 → 0

Minimum Cost: 80
RESULT

Thus, the Travelling Salesman Problem (TSP) was successfully solved using the
Branch and Bound technique.

You might also like