0% found this document useful (0 votes)
34 views15 pages

DAA Record

The program contains algorithms for solving several classic problems: 1. Matrix multiplication using Strassen's algorithm, topological sorting of graphs, heap sort, coin change, all-pairs shortest paths (Floyd-Warshall and Johnson's algorithms), knapsack problem, Dijkstra's algorithm, Huffman coding trees, and linear programming. 2. N-Queens problem using backtracking to find all configurations of queens on an N×N chessboard without conflicts. 3. Finding all subsets of a set that sum to a target value using backtracking recursion. So in summary, the program contains efficient algorithms for matrix operations, graph problems, optimization problems and backtracking solutions to combin

Uploaded by

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

DAA Record

The program contains algorithms for solving several classic problems: 1. Matrix multiplication using Strassen's algorithm, topological sorting of graphs, heap sort, coin change, all-pairs shortest paths (Floyd-Warshall and Johnson's algorithms), knapsack problem, Dijkstra's algorithm, Huffman coding trees, and linear programming. 2. N-Queens problem using backtracking to find all configurations of queens on an N×N chessboard without conflicts. 3. Finding all subsets of a set that sum to a target value using backtracking recursion. So in summary, the program contains efficient algorithms for matrix operations, graph problems, optimization problems and backtracking solutions to combin

Uploaded by

dharun0704
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 15

Program:

import numpy as np
def strassen_matrix_multiply(A, B):
# Check if matrices are compatible for multiplication
if A.shape[1] != B.shape[0]:
raise ValueError("Matrices are not compatible for multiplication")

# Base case: If matrices are 1x1, perform simple multiplication


if A.shape[0] == 1 and A.shape[1] == 1 and B.shape[0] == 1 and B.shape[1] ==
1:
return np.dot(A, B)

# Split matrices into quadrants


n = A.shape[0]
m = n // 2

A11 = A[:m, :m]


A12 = A[:m, m:]
A21 = A[m:, :m]
A22 = A[m:, m:]

B11 = B[:m, :m]


B12 = B[:m, m:]
B21 = B[m:, :m]
B22 = B[m:, m:]

# Recursive steps
P1 = strassen_matrix_multiply(A11 + A22, B11 + B22)
P2 = strassen_matrix_multiply(A21 + A22, B11)
P3 = strassen_matrix_multiply(A11, B12 - B22)
P4 = strassen_matrix_multiply(A22, B21 - B11)
P5 = strassen_matrix_multiply(A11 + A12, B22)
P6 = strassen_matrix_multiply(A21 - A11, B11 + B12)
P7 = strassen_matrix_multiply(A12 - A22, B21 + B22)

# Combine the results


C11 = P1 + P4 - P5 + P7
C12 = P3 + P5
C21 = P2 + P4
C22 = P1 - P2 + P3 + P6
# Concatenate the quadrants to form the resulting matrix
result = np.vstack((np.hstack((C11, C12)), np.hstack((C21, C22))))
return result

# 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]])
product = strassen_matrix_multiply(A, B)
print("Product of A and B:")
print(product)

Program:

from collections import defaultdict


def topological_sort(graph):
def dfs(node):
visited.add(node)
for neighbor in graph[node]:
if neighbor not in visited:
dfs(neighbor)
sorted_nodes.append(node)
visited = set()
sorted_nodes = []
for node in graph:
if node not in visited:
dfs(node)
return sorted_nodes[::-1]

# Example usage
graph = defaultdict(list)
graph[1] = [2, 3]
graph[2] = [4]
graph[3] = [4, 5]
graph[4] = [6]
graph[5] = []
graph[6] = []
sorted_order = topological_sort(graph)
print("Topological Sort Order:")
print(sorted_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)

# Perform sorting
for i in range(n - 1, 0, -1):
arr[0], arr[i] = arr[i], arr[0]
heapify(arr, i, 0)

# Example usage
arr = [12, 11, 13, 5, 6, 7]
heap_sort(arr)
print("Sorted array:")
print(arr)

Program :

def coin_change(coins, target):


dp = [float('inf')] * (target + 1)
dp[0] = 0
for coin in coins:
for i in range(coin, target + 1):
dp[i] = min(dp[i], dp[i - coin] + 1)
if dp[target] == float('inf'):
return -1

# Retrieve coin combination (optional)


coins_used = []
i = target
while i > 0:
for coin in coins:
if i - coin >= 0 and dp[i] - dp[i - coin] == 1:
coins_used.append(coin)
i -= coin
break
coins_used.reverse()
return dp[target], coins_used

# Example usage
coins = [1, 2, 5]
target = 11
min_coins, coin_combination = coin_change(coins, target)
print("Minimum number of coins needed:", min_coins)
print("Coin combination:", coin_combination)

Program:

Code for Warshall's Algorithm:

def warshall(adj_matrix):
num_vertices = len(adj_matrix)
tc = [row[:] for row in adj_matrix] # Create a copy of the adjacency matrix
for k in range(num_vertices):
for i in range(num_vertices):
for j in range(num_vertices):
tc[i][j] = tc[i][j] or (tc[i][k] and tc[k][j])
return tc

# Example usage
adj_matrix = [[0, 1, 0, 0],[0, 0, 0, 1],[0, 0, 0, 0],[1, 0, 1, 0]]
transitive_closure = warshall(adj_matrix)
print("Transitive Closure Matrix:")
for row in transitive_closure:
print(row)

Code for Floyd's Algorithm:

def floyd(adj_matrix):
num_vertices = len(adj_matrix)
dist = [row[:] for row in adj_matrix] # Create a copy of the adjacency matrix
for k in range(num_vertices):
for i in range(num_vertices):
for j in range(num_vertices):
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
return dist

# Example usage
adj_matrix = [[0, 1, float('inf'), 3],[2, 0, 4, float('inf')],[float('inf'), float('inf'), 0, 2],
[float('inf'), float('inf'), 1, 0]]
shortest_distances = floyd(adj_matrix)
print("Shortest Distance Matrix:")
for row in shortest_distances:
print(row)

Program :

def knapsack(items, weights, values, capacity):


n = len(items)
dp = [[0] * (capacity + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
for j in range(1, capacity + 1):
if weights[i - 1] <= j:
dp[i][j] = max(dp[i - 1][j], values[i - 1] + dp[i - 1][j - weights[i - 1]])
else:
dp[i][j] = dp[i - 1][j]
max_value = dp[n][capacity]

# Retrieve selected items (optional)


selected_items = []
i=n
j = capacity
while i > 0 and j > 0:
if dp[i][j] != dp[i - 1][j]:
selected_items.append(items[i - 1])
j -= weights[i - 1]
i -= 1
selected_items.reverse()
return max_value, selected_items

# Example usage
items = ['Item1', 'Item2', 'Item3', 'Item4', 'Item5']
weights = [2, 3, 4, 5, 6]
values = [5, 7, 9, 11, 13]
capacity = 10

max_value, selected_items = knapsack(items, weights, values, capacity)

print("Maximum value:", max_value)


print("Selected items:", selected_items)

Program:

import heapq

def dijkstra(graph, source):


distances = [float('inf')] * len(graph)
distances[source] = 0
pq = [(0, source)] # (distance, vertex)
while pq:
dist, u = heapq.heappop(pq)
if dist > distances[u]:
continue
for v, weight in graph[u]:
new_dist = dist + weight
if new_dist < distances[v]:
distances[v] = new_dist
heapq.heappush(pq, (new_dist, v))
return distances

# Example usage
graph = [[(1, 4), (2, 2)],[(2, 5), (3, 2)],[(1, 1), (3, 1)],[(4, 3)], []]

source_vertex = 0

shortest_distances = dijkstra(graph, source_vertex)


print("Shortest distances from vertex", source_vertex)
print(shortest_distances)

Program:

from queue import PriorityQueue

class Node:
def __init__(self, char, frequency):
self.char = char
self.frequency = frequency
self.left = None
self.right = None
def build_huffman_tree(characters, frequencies):
pq = PriorityQueue()
for i in range(len(characters)):
node = Node(characters[i], frequencies[i])
pq.put((node.frequency, node))
while pq.qsize() > 1:
freq1, node1 = pq.get()
freq2, node2 = pq.get()
new_node = Node(None, freq1 + freq2)
new_node.left = node1
new_node.right = node2
pq.put((new_node.frequency, new_node))
root = pq.get()[1]
return root
def generate_huffman_codes(root):
codes = {}

def dfs(node, code):


if node.char:
codes[node.char] = code
else:
dfs(node.left, code + '0')
dfs(node.right, code + '1')
dfs(root, '')
return codes

# Example usage
characters = ['A', 'B', 'C', 'D', 'E']
frequencies = [10, 7, 15, 4, 12]

root = build_huffman_tree(characters, frequencies)


huffman_codes = generate_huffman_codes(root)

print("Huffman Codes:")
for char, code in huffman_codes.items():
print(char, ":", code)
Program:

import numpy as np

from scipy.optimize import linprog

# Define the objective function coefficients


c = [3, 2]

# Define the constraint coefficients and RHS values


A = [[-1, 1],[3, 2],[1, 0]]
b = [1, 12, 3]

# Define the bounds for the variables


x_bounds = [(0, None), (0, None)]

# Solve the linear programming problem using the simplex method


result = linprog(c, A_ub=A, b_ub=b, bounds=x_bounds, method='simplex')

# Print the optimal solution and objective function value


print("Optimal Solution:")
print(result.x)
print("Objective Function Value:")
print(result.fun)

Program:

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

# Check if a queen can be placed at the current position without conflicts


# Check column
for i in range(row):
if board[i][col] == 1:
return False

# Check upper diagonal


i = row - 1
j = col - 1
while i >= 0 and j >= 0:
if board[i][j] == 1:
return False
i -= 1
j -= 1

# Check lower diagonal


i = row - 1
j = col + 1
while i >= 0 and j < N:
if board[i][j] == 1:
return False
i -= 1
j += 1
return True

def place_queens(row, board, N, solutions):


if row == N:

# All queens have been placed successfully


solutions.append(board.copy())
return
for col in range(N):
if is_safe(row, col, board, N):

# Place the queen at the current position


board[row][col] = 1

# Recursively place queens in the next row


place_queens(row + 1, board, N, solutions)

# Remove the queen from the current position


board[row][col] = 0

def solve_n_queen(N):
board = [[0] * N for _ in range(N)]
solutions = []
place_queens(0, board, N, solutions)
return solutions

# Example usage
N=4
solutions = solve_n_queen(N)

print("Number of solutions:", len(solutions))


for i, solution in enumerate(solutions):
print("Solution", i + 1)
for row in solution:
print(row)
print()
Program:

def find_subsets(nums, target_sum, index, subset, subsets):


if target_sum == 0:
subsets.append(subset[:]) # Add a copy of the subset to the subsets list
return
for i in range(index, len(nums)):
if nums[i] <= target_sum:
subset.append(nums[i])
find_subsets(nums, target_sum - nums[i], i + 1, subset, subsets)
subset.pop()

def subset_sum(nums, target_sum):


subsets = []
find_subsets(nums, target_sum, 0, [], subsets)
return subsets

# Example usage
nums = [2, 4, 6, 8]
target_sum = 8
result = subset_sum(nums, target_sum)
print("Subsets with a sum of", target_sum)
for subset in result:
print(subset)
Program:

import numpy as np

def branch_and_bound(cost_matrix):
N = cost_matrix.shape[0]
assignment_matrix = np.zeros((N, N), dtype=int)
selected_tasks = []
min_cost = float('inf')

def backtrack(selected_tasks, current_cost):


nonlocal min_cost
if current_cost > min_cost:
return
if len(selected_tasks) == N:
min_cost = current_cost
assignment_matrix.fill(0)
for i, task in enumerate(selected_tasks):
assignment_matrix[task][i] = 1
return
for task in range(N):
if task not in selected_tasks:
agent = np.argmin([cost_matrix[task][i] for i in range(N) if i not in
selected_tasks])
selected_tasks.append(task)
backtrack(selected_tasks, current_cost + cost_matrix[task][agent])
selected_tasks.remove(task)
backtrack(selected_tasks, 0)
return assignment_matrix, min_cost

# Example usage
cost_matrix = np.array([[5, 7, 3, 8],[9, 2, 6, 4],[1, 3, 8, 6],[7, 6, 4, 2]])
assignment, min_cost = branch_and_bound(cost_matrix)
print("Assignment Matrix:")
print(assignment)
print("Minimum Cost:", min_cost)

Program:

import numpy as np

def branch_and_bound(current_city, visited_cities, path, distance):


global min_distance, best_path
if len(visited_cities) == N and distances[current_city][0] < min_distance:
min_distance = distance + distances[current_city][0]
best_path = path[:]
return

for city in range(N):


if city not in visited_cities:
visited_cities.add(city)
path.append(city)
new_distance = distance + distances[current_city][city]
if new_distance < min_distance:
branch_and_bound(city, visited_cities, path, new_distance)
visited_cities.remove(city)
path.pop()

# Example usage
distances = np.array([[0, 2, 9, 10],[1, 0, 6, 4],[15, 7, 0, 8],[6, 3, 12, 0]])
N = distances.shape[0]
min_distance = float('inf')
best_path = []
branch_and_bound(0, {0}, [0], 0)
print("Best Path:", best_path)
print("Minimum Distance:", min_distance)

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy