Daa LM Practical Exercises
Daa LM Practical Exercises
AIM
The Aim is to implement recursive and non-recursive algorithms and study the order of growth
from log2n to n!
ALGORITHM
Step 1: Start the program.
Step 2: Implement recursive and non-recursive algorithms using log2n to n!
Step 3: Compute Factorial n*fact(n-1),Fibonacci series using recursive algorithm
Step 5: Compute the insertion sort using non recursive algorithm
Step 6: End the program
PROGRAM
1. A) Python code to implement Factorial
def recursive_factorial(n):
if n == 1:
return n
else:
return n * recursive_factorial(n-1)
num = 6
if num < 0:
print("Invalid input ! Please enter a positive number.")
elif num == 0:
print("Factorial of number 0 is 1")
else:
print("Factorial of number", num, "=", recursive_factorial(num))
OUTPUT
Factorial of number 6 = 720
2. B) Python code to implement Fibonacci series
def recursive_fibonacci(n):
if n <= 1:
return n
else:
return(recursive_fibonacci(n-1) + recursive_fibonacci(n-2))
n_terms = 10
# check if the number of terms is valid
if n_terms <= 0:
print("Invalid input ! Please input a positive value")
else:
print("Fibonacci series:")
for i in range(n_terms):
print(recursive_fibonacci(i))
OUTPUT
Fibonacci series:
0
1
1
2
3
5
8
13
21
34
NON-RECURSIVE ALGORITHM
def insertionSort(arr):
n = len(arr)
if n <= 1:
return
OUTPUT
Insertion sort
RESULT
Thus, program for recursive and non-recursive algorithm are given above are executed
successfully.
Exp No: 2 STRASSEN’S MATRIX MULTIPLICATION USING DIVIDE AND
Date: CONQUER
AIM
The Aim is to implement recursive and non-recursive algorithms and study the order of growth
from log2n to n!
ALGORITHM
Step 1: Start the program.
Step 2: Divide the matrices A and B into smaller sub matrices of the size n/2xn/2
Step 3: Using the formula of scalar additions and subtractions compute smaller matrices of size
n/2.
Step 4: Recursively compute the seven matrix products Pi=AiBi for i=1,2,…
Step 5: End the program
PROGRAM
x=[[0,2],[0,1]]
print("matrix x is:")
for i in range(len(x)):
print("\t",x[i])
y=[[0,0],[3,4]]
print("matrix y is:")
for i in range(len(y)):
print("\t",y[i])
def strassen(a,b):
S=[b[0][1]-b[1][1],
a[0][0]+a[0][1],
a[1][0]+a[1][1],
b[1][0]-b[0][0],
a[0][0]+a[1][1],
b[0][0]+b[1][1],
a[0][1]-a[1][1],
b[1][0]+b[1][1],
a[0][0]-a[1][0],
b[0][0]+b[0][1]]
P=[a[0][0]*S[0],
S[1]*b[1][1],
S[2]*b[0][0],
a[1][1]*S[3],
S[4]*S[5],
S[6]*S[7],
S[8]*S[9]]
C=[[P[4]+P[3]-P[1]+P[5],P[0]+P[1]],
[P[2]+P[3],
P[4]+P[0]-P[2]-P[6]]]
print("Strassen's Matrix multiplication of x and y is.")
print(S)
print(P)
print(C)
strassen(x,y)
OUTPUT:
Matrix X is : [0,2]
[0,1]
Matrix Y is : [0,0]
[3,4]
Strassen's Matrix multiplication of x and y is.
[-4,2,1,3,1,4,1,7,0,0]
[0,8,0,3,4,7,0]
[[6,8],[3,4]]
RESULT :
Thus the above program has been executed successfully and the required output is displayed.
Exp No: 3
DIVIDE AND CONQUER – TOPOLOGICAL SORTING
Date:
AIM
To implement Decrease and Conquer - Topological Sorting
ALGORITHM
Step 1: Create a stack to store the nodes.
Step 2: Initialize visited an array of size N to keep the record of visited nodes.
Step 3: Run a loop from 0 to N.
Step 4: if the node is not marked True in the visited array.
Step 5: Call the recursive function for topological sort and perform the following steps.
Step 6: Mark the current node as True in the visited array.
Step 7: Run a loop on all the nodes which have a directed edge to the current node.
Step 8: if the node is not marked true in the visited array: Recursively call the topological sort
function on the node and Push the current node in the stack.
Step 9: Print all the elements in the stack.
PROGRAM
from collections import defaultdict
class Graph:
def __init__(self,n):
self.graph = defaultdict(list)
self.N = n
def addEdge(self,m,n):
self.graph[m].append(n)
def sortUtil(self,n,visited,stack):
visited[n] = True
for element in self.graph[n]:
if visited[element] == False:
self.sortUtil(element,visited,stack)
stack.insert(0,n)
def topologicalSort(self):
visited = [False]*self.N
stack =[]
for element in range(self.N):
if visited[element] == False:
self.sortUtil(element,visited,stack)
print(stack)
graph = Graph(5)
graph.addEdge(0,1)
graph.addEdge(0,3)
graph.addEdge(1,2)
graph.addEdge(2,3)
graph.addEdge(2,4)
graph.addEdge(3,4)
print("The Topological Sort Of The Graph Is: ")
graph.topologicalSort()
OUTPUT:
The Topological Sort Of The Graph Is:
[0, 1, 2, 3, 4]
RESULT
Thus the above program has been executed successfully and the required output is displayed.
Exp No: 4
TRANSFORM AND CONQUER – HEAP SORT
Date:
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
def heapify(arr, n, i):
largest = i
l=2*i+1
r=2*i+2
if l < n and arr[i] < arr[l]:
largest = l
if r < n and arr[largest] < arr[r]:
largest = r
if largest != i:
arr[i],arr[largest] = arr[largest],arr[i]
heapify(arr, n, largest)
def heapSort(arr):
n = len(arr)
for i in range(n, -1, -1):
heapify(arr, n, i)
for i in range(n-1, 0, -1):
arr[i], arr[0] = arr[0], arr[i]
heapify(arr, i, 0)
arr = [2,5,3,8,6,5,4,7]
heapSort(arr)
n = len(arr)
print ("Sorted array is")
for i in range(n):
print (arr[i],end=" ")
OUTPUT:
Sorted array is
23455678
RESULT
Thus the above program has been executed successfully and the required output is displayed.
Exp No: 5(a)
DYNAMIC PROGRAMMING - COIN CHANGE PROBLEM
Date:
AIM
ALGORITHM
Step 2: Create an array[i], it represents the number of ways to make the sum i using the given
coin denominations.
Step 3: The outer loop iterates over the coins, and the inner loop iterates over the target sums.
For each array[j], it calculates the number of ways to make change using the current coin
denomination and the previous results stored in array[j].
Step 4: Array [sum] contains the total number of ways to make change for the given target sum
using the available coin denominations.
Step 5: Finally print no ways the coin given.
Step 6: Stop the program.
5a) PROGRAM
def getNumberOfWays(N, Coins):
ways = [0] * (N + 1);
ways[0] = 1;
for i in range(len(Coins)):
for j in range(len(ways)):
if (Coins[i] <= j):
ways[j] += ways[(int)(j - Coins[i])];
return ways[N];
def printArray(coins):
for i in coins:
print(i);
if __name__ == '__main__':
Coins = [1, 5, 10];
print("The Coins Array:");
printArray(Coins);
print("Solution:",end="");
print(getNumberOfWays(2, Coins));
OUTPUT:
The Coins Array:
1
5
10
Solution: 1
RESULT
Thus the above program has been executed successfully and the required output is displayed.
Exp No: 5(b)
DYNAMIC PROGRAMMING – FLOYD WARSHALL’S ALGORITHM
Date:
AIM
ALGORITHM
Step 1: Create a matrix A0 of dimension n*n where n is the number of vertices. The row and the
column are indexed as i and j respectively. i and j are the vertices of the graph.
Step 2: Each cell A[i][j] is filled with the distance from the ith vertex to the jth vertex. If there is
no path from ith vertex to jth vertex, the cell is left as infinity.
Step 3: Create a matrix A1 using matrix A0. The elements in the first column and the first row
are left as they are. The remaining cells are filled in the following way.
i) Let k be the intermediate vertex in the shortest path from source to destination. In this
step, k is the first vertex. A[i][j] is filled with (A[i][k] + A[k][j]) if (A[i][j] > A[i][k] +
A[k][j]).
ii) That is, if the direct distance from the source to the destination is greater than the path
through the vertex k, then the cell is filled with A[i][k] + A[k][j].
iii) In this step, k is vertex 1. We calculate the distance from source vertex to destination
vertex through this vertex k.
Step 4: Similarly, A2 is created using A1. The elements in the second column and the second
row are left as they are.
Step 6: Print A4 and it gives the shortest path between each pair of vertices.
nV = 4
INF = 999
def floyd_warshall(G):
distance = list(map(lambda i: list(map(lambda j: j, i)), G))
for k in range(nV):
for i in range(nV):
for j in range(nV):
distance[i][j] = min(distance[i][j], distance[i][k] + distance[k][j])
print_solution(distance)
def print_solution(distance):
for i in range(nV):
for j in range(nV):
if(distance[i][j] == INF):
print("INF", end=" ")
else:
print(distance[i][j], end=" ")
print(" ")
G = [[0, 3, INF, 5],
[2, 0, INF, 4],
[INF, 1, 0, INF],
[INF, INF, 2, 0]]
floyd_warshall(G)
OUTPUT
0 3 7 5
2 0 6 4
3 1 0 5
5 3 2 0
RESULT
Thus the above program has been executed successfully and the required output is
displayed.
Exp No: 5(c)
DYNAMIC PROGRAMMING – KNAPSACK PROBLEM
Date:
AIM
ALGORITHM
Step 2: Include the Nth item. Value of the Nth item plus maximum value obtained by remaining
N-1 items and remaining weight i.e. (W-weight of the Nth item).
Step 3: Exclude the Nth item. Maximum value obtained by N-1 items and W weight.
Step 4: If the weight of the ‘Nth‘ item is greater than ‘W’, then the Nth item cannot be included
and in Step 3 is the only possibility.
Step 5: Stop the program.
PROGRAM
def knapsack(wt, val, W, n):
if n == 0 or W == 0:
return 0
if t[n][W] != -1:
return t[n][W]
if wt[n-1] <= W:
t[n][W] = max(
val[n-1] + knapsack(
wt, val, W-wt[n-1], n-1),
knapsack(wt, val, W, n-1))
return t[n][W]
elif wt[n-1] > W:
t[n][W] = knapsack(wt, val, W, n-1)
return t[n][W]
if __name__ == '__main__':
profit = [60, 100, 120]
weight = [10, 20, 30]
W = 75
n = len(profit)
t = [[-1 for i in range(W + 1)] for j in range(n + 1)]
print(knapsack(weight, profit, W, n))
OUTPUT:
280
RESULT
Thus the above program has been executed successfully and the required output is
displayed.
Exp No: 6(a)
GREEDY TECHNIQUE – DIJKSTRA’S ALGORITHM
Date:
AIM
ALGORITHM
g.dijkstra(0)
OUTPUT
RESULT
Thus the above program has been executed successfully and the required output is displayed.
Exp No: 6(b)
GREEDY TECHNIQUE – HUFFMAN TREES AND CODES
Date:
AIM
ALGORITHM
OUTPUT
d -> 000
a -> 0010
b -> 0011
e -> 010
c -> 011
f -> 1
RESULT
Thus the above program has been executed successfully and the required output is displayed.
Exp No: 7
ITERATIVE IMPROVEMENT - SIMPLEX METHOD
Date:
AIM
ALGORITHM
Step 1: Start with the initial basis associated with the identity matrix.
i) For MAX problem, If all the relative profits are less than or equal to 0, then the
current basis is the optimal one. STOP. Else continue to 3.
ii) For MIN problem, if all the relative profits are greater than or equal to 0, then the
current basis is the optimal one. STOP. Else continue to 3.
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 '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.
RESULT:
Thus the above program has been executed successfully and the required output is displayed.
Exp No: 8(a)
BACKTRACKING – N-QUEEN PROBLEM
Date:
AIM
ALGORITHM
return True
def solveNQUtil(board, col):
if col >= N:
return True
for i in range(N):
if isSafe(board, i, col):
board[i][col] = 1
if solveNQUtil(board, col + 1) == True:
return True
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
if __name__ == '__main__':
solveNQ()
OUTPUT
. . Q .
Q . . .
. . . Q
. Q . .
RESULT:
Thus the above program has been executed successfully and the required output is displayed.
Exp No: 8(b)
BACKTRACKING – SUBSET SUM PROBLEM
Date:
AIM
ALGORITHM
RESULT:
Thus the above program has been executed successfully and the required output is displayed.
Exp No: 9
BRANCH AND BOUND - ASSIGNMENT PROBLEM
Date:
AIM
ALGORITHM
Cost (2, {3, 4}, 1) = ∝ ; the notation denotes we are starting at city 2, going through
cities 3, 4, and reaching 1. And the path cost is infinity.
cost(i, S, j)=min cost (i, S−{i}, j)+dist(i,j), where j∈S and i≠j
for i in range(N):
if (adj[curr_path[level-1]][i] != 0 and
visited[i] == False):
temp = curr_bound
curr_weight += adj[curr_path[level - 1]][i]
if level == 1:
curr_bound -= ((firstMin(adj, curr_path[level - 1]) +
firstMin(adj, i)) / 2)
else:
curr_bound -= ((secondMin(adj, curr_path[level - 1]) +
firstMin(adj, i)) / 2)
if curr_bound + curr_weight < final_res:
curr_path[level] = i
visited[i] = True
TSPRec(adj, curr_bound, curr_weight,
level + 1, curr_path, visited)
curr_weight -= adj[curr_path[level - 1]][i]
curr_bound = temp
visited = [False] * len(visited)
for j in range(level):
if curr_path[j] != -1:
visited[curr_path[j]] = True
def TSP(adj):
curr_bound = 0
curr_path = [-1] * (N + 1)
visited = [False] * N
for i in range(N):
curr_bound += (firstMin(adj, i) +
secondMin(adj, i))
curr_bound = math.ceil(curr_bound / 2)
visited[0] = True
curr_path[0] = 0
TSPRec(adj, curr_bound, 0, 1, curr_path, visited)
RESULT:
Thus the above program has been executed successfully and the required output is displayed.