DAA Final Manual (1)-2
DAA Final Manual (1)-2
Thalambur, Chennai-600130
ODD SEMESTER
Register No:
Year/Dept/Section:
2023-2024
Exp. Page No.
No
EX.NO. : 1
DIVIDE AND CONQURE – STRASSEN’S MATRIX MULTIPLICATION
DATE :
AIM
To do Divide and Conquer - Strassen's Matrix Multiplication
ALGORITHM
PROGRAM
import numpy as np
def strassen_algorithm(x, y):
if x.size == 1 or y.size == 1:
return x * y
n = x.shape[0]
if n % 2 == 1:
x = np.pad(x, (0, 1), mode='constant')
y = np.pad(y, (0, 1), mode='constant')
m = int(np.ceil(n / 2))
a = x[: m, : m]
b = x[: m, m:]
c = x[m:, : m]
d = x[m:, m:]
e = y[: m, : m]
f = y[: m, m:]
g = y[m:, : m]
h = y[m:, m:]
p1 = strassen_algorithm(a, f - h)
p2 = strassen_algorithm(a + b, h)
p3 = strassen_algorithm(c + d, e)
p4 = strassen_algorithm(d, g - e)
p5 = strassen_algorithm(a + d, e + h)
p6 = strassen_algorithm(b - d, g + h)
p7 = strassen_algorithm(a - c, e + f)
result = np.zeros((2 * m, 2 * m), dtype=np.int32)
result[: m, : m] = p5 + p4 - p2 + p6
result[: m, m:] = p1 + p2
result[m:, : m] = p3 + p4
result[m:, m:] = p1 + p5 - p3 - p7
return result[: n, : n]
#input of two matrix
x = np.array([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [2, 2, 2, 2]])
y = np.array([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [2, 2, 2, 2]])
print('Matrix multiplication result: ')
print(strassen_algorithm(x, y))
OUTPUT
Matrix multiplication result:
[[ 8 8 8 8]
[16 16 16 16]
[24 24 24 24]
[16 16 16 16]]
RESULT
The above program has been executed successfully and the required output is displayed
EX.NO. : 2
DATE :
AIM
To implement Decrease and Conquer - Topological Sorting
ALGORITHM
PROGRAM
def topologicalSort(self):
# Mark all the vertices as not visited visited
= [False]*self.V
stack = []
# Call the recursive helper function to store Topological
# Sort starting from all vertices one by one
for i in range(self.V):
if visited[i] == False:
self.topologicalSortUtil(i, visited, stack)
# Print contents of the stack print(stack[::-1]) # return list
in reverse order
g = Graph(6)
g.addEdge(5, 2)
g.addEdge(5, 0)
g.addEdge(4, 0)
g.addEdge(4, 1)
g.addEdge(2, 3)
g.addEdge(3, 1)
print ("Topological Sort of the given graph")
g.topologicalSort()
OUTPUT
Topological Sort of the given graph
[5, 4, 2, 3, 1, 0]
RESULT
The above program has been executed successfully and the required output is displayed
EX.NO. : 3
DATE : TEANSFORM AND CONQUER – HEAP SORT
AIM
To write a python program to Transform and Conquer - Heap Sort
ALGORITHM
Step 1: First convert the array into a heap data structure using heapify,
Step 2: one by one delete the root node of the Max-heap and replace it with the last node in the heap
and then heapify the root of the heap.
Step 3: Repeat this process until the size of the heap is greater than 1.
Step 4: Build a max heap from the input data.
Step 5: At this point, the maximum element is stored at the root of the heap. Step 6: Replace it with
the last item of the heap followed by reducing the size of the heap by 1.
Step 7: Finally, heapify the root of the tree.
Step 8: Repeat step 2 while the size of the heap is greater than 1.
PROGRAM
OUTPUT
Sorted array is
5
6
7
11
12
13
RESULT
The above program has been executed successfully and the required output is displayed.
EX.NO. : 4 DYNAMIC PROGRAMMING – COIN CHANGING PROBLEM,
WARSHALL’S AND FLOYD’S ALAGRITHMS, KNAPSACK
DATE :
PROBLEM
AIM
To write a python program to implement Dynamic programming - Coin change Problem, Warshall's
and Floyd's algorithms, Knapsack Problem
ALGORITHM
Coinbase Problem
Step 1: Start the program.
Step 2: Create a 2-D vector to store the Overlapping Solutions
Step 3: Keep Track of the overlapping subproblems while Traversing the array of coins
Step 4: Recall them whenever needed
Step 5: End the program
Step 7: k is not an intermediate vertex in the shortest path from i to j. We keep the value of dist[i][j]
as it is.
Step 8: k is an intermediate vertex in the shortest path from i to j. We update the value of
dist[i][j] as dist[i][k] + dist[k][j] if dist[i][j] > dist[i][k] + dist[k][j]
Step 9: End the program
Knapsack Problem
Step 1: Start the program.
Step 2: The maximum value obtained from ‘N’ items is the max of the following two values.
Step 3: Maximum value obtained by N-1 items and W weight (excluding nth item)
Step 4: Value of nth item plus maximum value obtained by N-1 items and W minus the weight of
the Nth item (including Nth item)
Step 5: If the weight of the ‘Nth’ item is greater than ‘W’, then the Nth item cannot be included and
Case 1 is the only possibility.
Step 6: End the program
PROGRAM
Output
0 5 15 10
20 0 10 5
30 35 0 15
15 20 5 0
Knapsack problem
return K[n][W]
val = [60, 100, 120]
wt = [10, 20, 30]
W = 50
n = len(val)
print(knapSack(W, wt, val, n))
OUTPUT:
220
RESULT
The above program has been executed successfully and the required output is displayed.
EX.NO. : 5
DATE : GREEDY TECHNIQUE – DIJKSTRA’S ALGORITHM, HUFFMAN
TREES, AND CODES
AIM
To write a python program to implement Greedy Technique - Dijkstra's algorithm, Huffman
Trees, and codes
ALGORITHM
Step 1: Create a set sptSet (shortest path tree set) that keeps track of vertices included in the shortest
path tree.
Step 3: Assign the distance value as 0 for the source vertex so that it is picked first.
Step 5: Pick a vertex u that is not there in sptSet and has a minimum distance value.
Step 7: Update the distance value of all adjacent vertices of u. To update the distance values, iterate
through all adjacent vertices. For every adjacent vertex v, if the sum of a distance value of u
(from source) and weight of edge u-v, is less than the distance value of v, then update the
distance value of v.
PROGRAM
Dijkstra’s algorithm
num_of_vertex = 7
def minimumDistance(distance, visited):
_min = 1e11
min_index = 1e11
for i in range(num_of_vertex):
if not visited[i] and distance[i] & lt; = _min:
_min = distance[i]
min_index = i
return min_index
def printParentNode(parent, i):
if parent[i] == -1:
return
printParentNode(parent, parent[i])
print("{} ".format(i + 1), end = "")
def dijkstra(graph, src):
distance = list()
visited = list()
parent = list()
for i in range(num_of_vertex):
parent.append(-1)
distance.append(1e11)
visited.append(False)
distance[src] = 0
for i in range(num_of_vertex - 1):
U = minimumDistance(distance, visited)
visited[U] = True
for j in range(num_of_vertex):
curr_distance = distance[U] + graph[U][j]
if not visited[j] and graph[U][j] and curr_distance & lt; distance[j]:
parent[j] = U
distance[j] = curr_distance
print("Vertex\t\tDistance\tPath")
for i in range(num_of_vertex):
print("{}->{}\t\t{}\t\t{}
".format(src + 1, i + 1, distance[i], src + 1), end = "")
printParentNode(parent, i)
print("")
graph = [
[0, 1, 7, 6, 0, 0, 0],
[1, 0, 9, 0, 0, 3, 0],
[7, 9, 0, 0, 0, 0, 1],
[6, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 2, 0, 0, 0],
[0, 3, 0, 0, 0, 0, 3],
[0, 0, 0, 0, 5, 3, 0]
]
dijkstra(graph, 0)
Output:
Vertex Distance Path
1->1 0 1
1->2 1 1 2
1->3 7 1 3
1->4 6 1 4
1->5 8 1 4 5
1->6 4 1 2 6
1->7 7 1 2 67
RESULT
The above program has been executed successfully and the required output is displayed
EX.NO. : 6
DATE : ITERATIVE IMPROVEMENT – SIMPLEX METHOD
AIM
To write a program to implement Iterative improvement - Simplex Method.
ALGORITHM
Step 1: Start with the initial basis associated with the identity matrix.
Step 2: Calculate the relative profits.
Step 3: Find the column corresponding to max relative profit. Say column k has the max Rel. profit. So
xk will enter the basis.
Step 4: Perform a min ratio test to determine which variable will leave the basis.
min ratio test: XBr/y_{rk} = min\{XB_i/y_{ik}\}
The index of the min element i.e 'r' will determine the leaving variable.
The basic variable at index r will leave the basis.
Step 5: It's evident that the entered variable will not form an identity matrix, so we will have to perform
row operations to make it identity again.
Step 6: Find the pivot element. The element at index (r, k) will be the pivot element and row r will be the
pivot row.
Step 7:Divide the rth row by pivot to make it 1. And subtract c*(rth row) from other rows to make
them 0, where c is the coefficient required to make that row 0.
PROGRAM
import numpy as np
from fractions import Fraction # so that numbers are not displayed in decimal.
reached = 0
itr = 1
unbounded = 0
alternate = 0
while reached == 0:
b_var = table[:, 0]
# checking for alternate solution
while i<len(A[0]):
j=0
present = 0
while j<len(b_var):
if int(b_var[j]) == i:
present = 1
break;
j+= 1
if present == 0:
if rel_prof[i] == 0:
alternate = 1
print("Case of Alternate found")
# print(i, end =" ")
i+= 1
print()
flag = 0
for profit in rel_prof:
if profit>0:
flag = 1
break
# if all relative profits <= 0 if
flag == 0:
print("All profits are <= 0, optimality reached")
reached = 1
break
k = rel_prof.index(max(rel_prof))
min = 99999
i = 0;
r = -1
while i<len(table):
if (table[:, 2][i]>0 and table[:, 3 + k][i]>0):
val = table[:, 2][i]/table[:, 3 + k][i]
if val<min:
min = val
r = i # leaving variable
i+= 1
if r == -1:
unbounded = 1
print("Case of Unbounded")
break
pivot = table[r][3 + k]
print("pivot element: ", end =" ")
print(Fraction(pivot).limit_denominator(100))
i=0
while i<len(table):
if i != r:
table[i, 2:len(table[0])] = table[i,
2:len(table[0])] - table[i][3 + k] *
table[r, 2:len(table[0])]
i += 1
table[r][0] = k
table[r][1] = c[k]
print()
print()
itr+= 1
print()
print("***************************************************************")
if unbounded == 1:
print("UNBOUNDED LPP")
exit()
if alternate == 1:
print("ALTERNATE Solution")
print("optimal table:")
print("B \tCB \tXB \ty1 \ty2 \ty3 \ty4")
for row in table:
for el in row:
print(Fraction(str(el)).limit_denominator(100), end ='\t')
print()
print()
print("value of Z at optimality: ", end =" ")
basis = []
i=0
sum = 0
while i<len(table):
sum += c[int(table[i][0])]*table[i][2]
temp = "x"+str(int(table[i][0])+1)
basis.append(temp)
i+= 1
if MIN == 1:
print(-Fraction(str(sum)).limit_denominator(100))
else:
print(Fraction(str(sum)).limit_denominator(100))
print("Final Basis: ", end =" ")
print(basis)
print("Simplex Finished...")
print()
RESULT
The above program has been executed successfully and the required output is displayed.
EX.NO. : 7
BACKTRACKING – N-QUEEN PROBLEM, SUBSET SUM PROBLEM
DATE :
AIM
To write a program to implement Backtracking - N-Queen problem, Subset Sum Problem
ALGORITHM
Step 1: Make a board, and make a space to collect all solution states.
Step 2: Start in the topmost row.
Step 3: Make a recursive function that takes the state of the board and the current row
number as its parameter.
Step 4: Fill a queen in a safe place and use this state of the board to advance to the next
recursive call, add 1 to the current row. Revert the state of the board after making
the call.
a) Safe function checks the current column, left top diagonal, and right top diagonal.
b) If no queen is present then fill else return false and stop exploring that state
and track back to the next possible solution state
Step 5: Keep calling the function till the current row is out of bounds.
Step 6: If the current row reaches the number of rows in the board then the board is filled.
Step 7: Store the state and return.
PROGRAM
N-Queen problem
global N
N=4
def printSolution(board):
for i in range(N):
for j in range(N):
print (board[i][j],end=' ')
print()
def isSafe(board, row, col):
for i in range(col):
if board[row][i] == 1:
return False
return True
if col >= N:
return True
for i in range(N):
if isSafe(board, i, col):
board[i][col] = 1
board[i][col] = 0
return False
def solveNQ():
board = [ [0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
]
if solveNQUtil(board, 0) == False:
print ("Solution does not exist")
return False
printSolution(board)
return True
solveNQ()
OUTPUT
0010
1000
0001
0100
Subset problem
if (sum == 0):
return True
if (n == 0):
return False
OUTPUT
RESULT
The above program has been executed successfully and the required output is displayed.
EX.NO. : 8 BRANCH AND BOND – ASSIGNMENT PROBLEM, TRAVELING
DATE : SALESMAN PROBLEM
AIM
To write a python program to implement Branch and Bound - Assignment problem, Traveling
Salesman Problem
ALGORITHM
Step 1: In the Branch and Bound method, for the current node in the tree, we compute a bound on
the best possible solution that we can get if we down this node.
Step 2: If the bound on the best possible solution itself is worse than the current best (best computed
so far)
Step 3: Then we ignore the subtree rooted with the node.
Step 4: Note that the cost through a node includes two costs.
Step 5: Cost of reaching the node from the root (When we reach a node, we have this cost
computed)
Step 6: Cost of reaching an answer from the current node to a leaf (We compute a bound on this
cost to decide whether to ignore subtree with this node or not).
PROGRAM
from sys import maxsize
from itertools import permutations
V=4
min_path = maxsize
next_permutation=permutations(vertex)
for i in next_permutation:
current_pathweight = 0
k=s
for j in i:
current_pathweight += graph[k][j]
k=j
current_pathweight += graph[k][s]
min_path = min(min_path, current_pathweight)
return min_path
if __name__ == "__main__":
graph = [[0, 10, 15, 20], [10, 0, 35, 25],
[15, 35, 0, 30], [20, 25, 30, 0]]
s=0
print(travellingSalesmanProblem(graph, s))
OUTPUT
RESULT
The above program has been executed successfully and the required output is displayed.