0% found this document useful (0 votes)
3 views37 pages

CS3401 Lab Manual Final

The document is a laboratory manual for the CS3401 Algorithms course at Arasu Engineering College, detailing the vision, mission, program educational objectives, and specific outcomes for the Computer Science and Engineering department. It includes a syllabus with various algorithmic exercises, such as searching and sorting algorithms, graph algorithms, and approximation algorithms, along with practical exercises and expected course outcomes. The manual is prepared by Mrs. R. Kalaiselvi and approved by Dr. Kalaimani Shanmugam.

Uploaded by

Vetri Vijayan
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)
3 views37 pages

CS3401 Lab Manual Final

The document is a laboratory manual for the CS3401 Algorithms course at Arasu Engineering College, detailing the vision, mission, program educational objectives, and specific outcomes for the Computer Science and Engineering department. It includes a syllabus with various algorithmic exercises, such as searching and sorting algorithms, graph algorithms, and approximation algorithms, along with practical exercises and expected course outcomes. The manual is prepared by Mrs. R. Kalaiselvi and approved by Dr. Kalaimani Shanmugam.

Uploaded by

Vetri Vijayan
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/ 37

ARASU ENGINEERING COLLEGE

Chennai Main Road, Kumbakonam – 612501

DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING

CS3401 - ALGORITHM LABORATORY

IV SEMESTER – R 2021

LABORATORY MANUAL

Prepared By: Approved By:

Mrs. R. Kalaiselvi Dr. Kalaimani Shanmugam


Assistant Professor Professor & Head
Department of CSE Department of CSE

IQAC
ARASU ENGINEERING COLLEGE, KUMBAKONAM
DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING
VISION:
To be in the forefront of Computer Science and Engineering by producing competing
professional with innovative skills, moral values, and societal concerns with a commitment towards
building a strong nation.
MISSION:
DM1 (Problem – Solving Skills):
To equip students with fundamental computing knowledge and problem - solving skills which
are necessary to solve real-world engineering challenges to meet industry and societal needs.
DM2 (Quality Education):
To impart quality education through continuous Teaching – Learning process, including
interdisciplinary areas that extend the scope of Computer Science.
DM3 (Societal Commitment):
To inculcate students with analytical ability, innovative spirit and entrepreneur skills with
ethical values and societal commitment.

Program Educational Objectives (PEOs):

PEO1 (Computational Ability):


Graduates will have an ability to work on different domains of Computing Technologies and
have a successful career in industries or as entrepreneurs.
PEO2 (Quality Professional):
Graduates will exhibit professionalism, team spirit, problem-solving skills, leadership skills and
will have an ability to adapt with emerging technological changes.
PEO3 (Ethical Values):
Graduates will practice their profession conforming towards ethical values with societal
responsibility and environmental concern.
Program Specific Outcomes (PSOs):
PSO1 (Software Skills):
To impart knowledge for the development of quality software for scientific and business
applications by applying fundamental and advanced concepts of Computer Science.
PSO2 (Professional Skills):
To develop practical competency to work in industries and manage different projects
effectively using modern tools with professional behavior and ethics.
Syllabus

CS3401 ALGORITHMS LTPC


3024
Searching and Sorting Algorithms
1. Implement Linear Search. Determine the time required to search for an element. Repeat the
experiment for different values of n, the number of elements in the list to be searched and plot a
graph of the time taken versus n.
2. Implement recursive Binary Search. Determine the time required to search an element. Repeat
the experiment for different values of n, the number of elements in the list to be searched and plot a
graph of the time taken versus n.
3. Given a text txt [0...n-1] and a pattern pat [0...m-1], write a function search (char pat[ ], char txt [ ])
that prints all occurrences of pat [ ] in txt [ ]. You may assume that n > m.
4. Sort a given set of elements using the Insertion sort and Heap sort methods and determine the
time required to sort the elements. Repeat the experiment for different values of n, the number of
elements in the list to be sorted and plot a graph of the time taken versus n.

Graph Algorithms
1. Develop a program to implement graph traversal using Breadth First Search
2. Develop a program to implement graph traversal using Depth First Search
3. From a given vertex in a weighted connected graph, develop a program to find the shortest
paths to other vertices using Dijkstra’s algorithm.
4. Find the minimum cost spanning tree of a given undirected graph using Prim’s algorithm.
5. Implement Floyd’s algorithm for the All-Pairs- Shortest-Paths problem.
6. Compute the transitive closure of a given directed graph using Warshall's algorithm.

Algorithm Design Techniques


1. Develop a program to find out the maximum and minimum numbers in a given list of n numbers
using the divide and conquer technique.
2. Implement Merge sort and Quick sort methods to sort an array of elements and determine the time
required to sort. Repeat the experiment for different values of n, the number of elements in the list to
be sorted and plot a graph of the time taken versus n.

State Space Search Algorithms


1. Implement N Queens problem using Backtracking.

Approximation Algorithms Randomized Algorithms


1. Implement any scheme to find the optimal solution for the Traveling Salesperson problem and then
solve the same problem instance using any approximation algorithm and determine the error in the
approximation.
2. Implement randomized algorithms for finding the kth smallest number.

The programs can be implemented in C/C++/JAVA/ Python.


PRACTICAL EXERCISES: 30 PERIODS

COURSE OUTCOMES:
At the end of this course, the students will be able to:
CO1: Analyze the efficiency of algorithms using various frameworks
CO2: Apply graph algorithms to solve problems and analyze their efficiency.
CO3: Make use of algorithm design techniques like divide and conquer, dynamic programming and
greedy techniques to solve problems
CO4: Use the state space tree method for solving problems.
CO5: Solve problems using approximation algorithms and randomized algorithms
List of Programs

Ex. No PROGRAMS

1. Linear Search

2. Binary Search

3. Pattern Matching

4. Sorting the elements using Insertion and Heap

5. Graph Traversal using Breadth First Search

6. Graph Traversal using Depth First Search

7. Dijkstra’s Algorithm

8. Prim’s Algorithm

9. Floyd’s Algorithm

10. Warshall’s Algorithm

11. State Space Search

12. Travelling Salesman Problem

13. Merge Sort

14. Quick Sort

15. Randomized Algorithms for kth Smallest element

Additional Experiments

16. Matrix Multiplication

17. Finding Maximum and minimum element in the given array


Ex. No: 1 Linear Search

Aim

To implement Linear Search and determine the time required to search for an element.
Repeat the experiment for different values of n, the number of elements in the list to be searched and
plot a graph of the time taken versus n.

Algorithm

1. Create the linear search() function.


2. Declare the list1, n, and key value to be found as three parameters.
3. Initialize the for a loop.
4. Compare the value of the key with each element as you iterate.
5. Return index if the element is present.
6. else return element is absent.

Program
import matplotlib.pyplot as plt
import numpy as np
import timeit import
math import random
def linear_Search(list1,n,key):
for i in range(0,n):
if(list1[i]==key):
return i
return -1
list1=[1,3,5,4,7,9]
key=7
n=len(list1)
res=linear_Search(list1,n,key)
if(res==-1):
print("element not found")
else:
print("element found at index:",res)
def contains(lst,x):
for y in lst:
if x==y:
return True
return False
ns=np.linspace(10,10_000,100,dtype=int)
ts=[timeit.timeit('contains(lst,0)',
setup='lst=list(range({}));random.shuffle(lst)'.format(n),
globals=globals(),number=100) for n in ns]
plt.plot(ns,ts,'or')
degree=4
coeffs=np.polyfit(ns,ts,degree)
p=np.poly1d(coeffs)
plt.plot(ns,[p(n) for n in ns],'-r')
ts=[timeit.timeit('contains(lst,-1)',
setup='lst=list(range({}));random.shuffle(lst)'.format(n), globals=globals(),
number=100)
for n in ns]
plt.plot(ns,ts,'ob')
degree=4
coeffs=np.polyfit(ns,ts,degree)
p=np.poly1d(coeffs)
plt.plot(ns,[p(n) for n in ns],'-b')

OUTPUT
element found at index: 4

Result

Thus the program has been created, executed and the output is verified.
Ex. No: 2 Binary Search

Aim

To implement recursive Binary Search and determine the time required to search an element.
Repeat the experiment for different values of n, the number of elements in the list to be searched and
plot a graph of the time taken versus n.

Algorithm

1. Create the binary search() function.


2. Declare the num and target as two parameters.
3. Initialize start=0 and end=length minus 1.
4. Check if target is greater than the mid element then end=mid-1
5. Else if target is less than the mid element then start=mid +1
6. Else return mid element

Program

import matplotlib.pyplot as plt


import numpy as np
import timeit import
math import random
def search(nums,target):
start=0
end=len(nums)-1
while start<=end:
mid=start+(end-start)//2
if nums[mid]>target:
end=mid-1
elif nums[mid]<target:
satrt=mid+1
else:
return mid
return -1
if name ==' main ':
nums=[2,12,15,17,27,29,45]
target=17
print(search(nums,target))
def contains(lst,x):
lo=0 hi=len(lst)-1
while lo <= hi:
mid=(lo+hi)//2 if
x<lst[mid]:
hi=mid-1
elif x>lst[mid]:
lo=mid+1
else:
return True
else:
return False
ns=np.linspace(10,10_000,100,dtype=int)
ts=[timeit.timeit('contains(lst,0)',
setup='lst=list(range({}));random.shuffle(lst)'.format(n), globals=globals(),
number=100)
for n in ns]
plt.plot(ns,ts,'or')
degree=4
coeffs=np.polyfit(ns,ts,degree)
p=np.poly1d(coeffs)
plt.plot(ns,[p(n) for n in ns],'-b')

OUTPUT

Result:

Thus the program has been created, executed and the output is verified.
Ex. No: 3 Pattern Matching

Aim
To write a function search (char pat [ ], char txt [ ]) that prints all occurrences of pat [ ] in txt [ ].

Algorithm

1. Create the search function and declare the two parameters pat and txt.
2. Initialize the for loop i=0 to i≤N-M+1, and the inner loop will range from j=0 to j<m, where ‘M’ is
the length of the input pattern and N is the length of the text string.
3. If a match is not found, we will break from the loop(using the 'break' keyword), and the j
pointer of the inner loop will move one index more and start the search algorithm in the next
window
4. If a match is found, we will match the entire pattern with the current window of the text string.
And if found the pattern string is found.print the result.

Program
# Python3 program for Naive Pattern
# Searching algorithm
def search(pat, txt):
M = len(pat)
N = len(txt)
# A loop to slide pat[] one by one */
for i in range(N - M + 1):
j=0
# For current index i, check
# for pattern match */
while(j < M):
if (txt[i + j] != pat[j]):
break
j += 1

if (j == M):
print("Pattern found at index ", i)
# Driver's Code
if __name__ == '__main__':
txt = "AABAACAADAABAAABAA"
pat = "AABA"

# Function call
search(pat, txt)

Output
Pattern found at index 0
Pattern found at index 9
Pattern found at index 13

Result:

Thus the program has been created, executed and the output is verified.
Ex. No: 4 Sorting the elements using Insertion and Heap

Aim
To sort a given set of elements using the Insertion sort and Heap sort methods and determine
the time required to sort the elements. Repeat the experiment for different values of n, the number of
elements in the list to be sorted and plot a graph of the time taken versus n.

Algorithm

1. Create the insertion sort function.


2. Initialize the for loop i=1 to array length.
3. If it is the first element, then place it in the sorted sub-array.
4. Pick the next element.
5. Compare the picked element with all the elements in sorted sub-array.
6. Shift all the elements in the sorted sub-array that are greater than the picked element to be
sorted.
7. Insert the element at the desired place.
8. Repeat the above steps until the array is completely sorted.

Program
import matplotlib.pyplot as plt
import numpy as np
import timeit import
math import random
def insertionSort(arr):
for i in range(1,len(arr)):
key=arr[i]
j=i-1
while j>=0 and key<arr[j]:
arr[j+1]=arr[j]
j-=1
arr[j+1]=key
arr=[12,11,13,5,6]
insertionSort(arr)
for i in range(len(arr)):
print("%d"%arr[i])
def insertion_sort(lst):
for i in range(1,len(lst)):
for j in range(i,0,-1):
if lst[j-1]>lst[j]:
lst[j-1],lst[j]=lst[j],lst[j-1]
else:
break
ns=np.linspace(100,2000,15,dtype=int)
ts=[timeit.timeit('insertion_sort(lst)',
setup='lst=list(range({}));random.shuffle(lst)'.format(n),
globals=globals(),
number=1)
for n in ns]
plt.plot(ns,ts,'or')
degree=4
coeffs=np.polyfit(ns,ts,degree)
p=np.poly1d(coeffs)
plt.plot(ns,[p(n) for n in ns],'-r')

OUTPUT
5
6
11
12
13
Heap Sort

# Python program for implementation of heap Sort


# To heapify subtree rooted at index i.
# n is size of heap
def heapify(arr, N, i):
largest = i # Initialize largest as root
l=2*i+1 # left = 2*i + 1
r=2*i+2 # right = 2*i + 2
# See if left child of root exists and is
# greater than root
if l < N and arr[largest] <arr[l]:
largest = l
# See if right child of root exists and is
# greater than root
if r < N and arr[largest] <arr[r]:
largest = r
# Change root, if needed
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i] # swap
# Heapify the root.
heapify(arr, N, largest)
# The main function to sort an array of given size
def heapSort(arr):
N = len(arr)
# Build a maxheap.
for i in range(N//2 - 1, -1, -1):
heapify(arr, N, i)

# One by one extract elements


for i in range(N-1, 0, -1):
arr[i], arr[0] = arr[0], arr[i] # swap
heapify(arr, i, 0)
# Driver's code
if __name__ == '__main__':
arr = [12, 11, 13, 5, 6, 7]
# Function call
heapSort(arr)
N = len(arr)
print("Sorted array is")
for i in range(N):
print("%d" % arr[i], end=" ")

Output
Sorted array is
5 6 7 11 12 13

Result:
Thus the program has been created, executed and the output is verified.
Ex. No: 5 Graph Traversal using Breadth First Search

Aim:

To develop a program to implement graphs traversal using Breadth First Search.

Algorithm

1. Start node to the Queue.


2. For every node, set that they don't have a defined parent node.
3. Until the Queue is empty:
 Extract the node from the beginning of the Queue.
 Perform output processing.
 For every neighbor of the current node that doesn't have a defined parent (is not
visited), add it to the Queue, and set the current node as their parent.

Program

from collections import defaultdict

class Graph:

# Constructor

def __init__(self):

# default dictionary to store graph

self.graph = defaultdict(list)

# function to add an edge to graph

def addEdge(self,u,v):

self.graph[u].append(v)

# Function to print a BFS of graph

def BFS(self, s):

# Mark all the vertices as not visited

visited = [False] * (len(self.graph))

# Create a queue for BFS

queue = []
# Mark the source node as

# visited and enqueue it

queue.append(s)

visited[s] = True

while queue:

# Dequeue a vertex from

# queue and print it

s = queue.pop(0)

print (s, end = " ")

for i in self.graph[s]:

if visited[i] == False:

queue.append(i)

visited[i] = True

g = Graph()

g.addEdge(0, 1)

g.addEdge(0, 2)

g.addEdge(1, 2)

g.addEdge(2, 0)

g.addEdge(2, 3)

g.addEdge(3, 3)

print ("Following is Breadth First Traversal" (starting from vertex 2)")

g.BFS(2)

Output

Following is Breadth First Traversal(starting from vertex 2)


2031

Result :

Thus the program has been created, executed and the output is verified.
Ex. No: 6 Graph Traversal using Depth First Search

Aim

To develop a program to implement graph traversal using Depth First Search

Algorithm

1. Create a recursive function that takes the index of the node and a visited array.
2. Mark the current node as visited and print the node.
3. Traverse all the adjacent and unmarked nodes and call the recursive function with the
index of the adjacent node.

Program

from collections import defaultdict


class Graph:
def init (self):
self.graph=defaultdict(list)
def addEdge(self,u,v):
self.graph[u].append(v)
def DFSUtil(self,v,visited):
visited[v]=True print (v)
for i in self.graph[v]: if
visited[i]==False:
self.DFSUtil(i,visited) def
DFS(self):
V=len(self.graph)
visited=[False]*(V) for i in
range(V):
if visited[i]==False:
self.DFSUtil(i,visited)
g=Graph()
g.addEdge(0,1)
g.addEdge(0,2)g.add
Edge(1,2)
g.addEdge(2,0)
g.addEdge(2,3)
g.addEdge(3,3)
print("Following is Depth First Traversal")
g.DFS()

Output:

Following is Depth First Traversal

0 1 2 3
Result:

Thus the program has been created, executed and the output is verified.
Ex. No: 7 Dijkstra’s Algorithm

Aim
To develop a program to find the shortest paths to other vertices using Dijkstra’s algorithm.

Algorithm

1. Create a set sptSet (shortest path tree set) that keeps track of vertices included in shortest
path tree, i.e., whose minimum distance from source is calculated and finalized. Initially, this
set is empty.
2. Assign a distance value to all vertices in the input graph. Initialize all distance values as
INFINITE. Assign distance value as 0 for the source vertex so that it is picked first.
3. While sptSet doesn’t include all vertices:
 Pick a vertex u which is not there in sptSet and has minimum distance value.
 Include u to sptSet.
 Update 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

class Graph():

class Graph():
def init (self, vertices):
self.V = vertices
self.graph = [[0 for column in range(vertices)]
for row in range(vertices)]
def printSolution(self, dist):
print("Vertex \t Distance from Source")
for node in range(self.V):
print(node, "\t\t", dist[node])
def minDistance(self, dist, sptSet):
min = 1e7
for v in range(self.V):
if dist[v] < min and sptSet[v] == False:
min = dist[v]
min_index = v
return min_index def
dijkstra(self, src):
dist = [1e7] * self.V
dist[src] = 0
sptSet = [False] * self.V for cout
in range(self.V):
u = self.minDistance(dist, sptSet)
sptSet[u] = True
for v in range(self.V):
if (self.graph[u][v] > 0 and
sptSet[v] == False and
dist[v] > dist[u] + self.graph[u][v]):
dist[v] = dist[u] + self.graph[u][v]

self.printSolution(dist)

g = Graph(9)
g.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] ]
g.dijkstra(0)

Output:

Vertex Distance from Source


0 0
1 4
2 12
3 19
4 21
5 11
6 9
7 8
8 14

Result:

Thus the program has been created, executed and the output is verified.
Ex. No: 8 Prim’s Algorithm

Aim

To find the minimum cost spanning tree of a given undirected graph using Prim’s algorithm.

Algorithm

1. Create a set mstSet that keeps track of vertices already included in MST.
2. Assign a key value to all vertices in the input graph. Initialize all key values as INFINITE.
Assign the key value as 0 for the first vertex so that it is picked first.
3. While mstSet doesn’t include all vertices
 Pick a vertex u that is not there in mstSet and has a minimum key value.
 Include u in the mstSet.
 Update the key value of all adjacent vertices of u. To update the key values, iterate
through all adjacent vertices.
 For every adjacent vertex v, if the weight of edge u-v is less than the
previous key value of v, update the key value as the weight of u-v.

Program
class Graph:
def init (self, num_of_nodes):
self.m_num_of_nodes = num_of_nodes
self.m_graph = [[0 for column in range(num_of_nodes)]
for row in range(num_of_nodes)]
def add_edge(self, node1, node2, weight):
self.m_graph[node1][node2] = weight
self.m_graph[node2][node1] = weight
def prims_mst(self): postitive_inf =
float('inf')
selected_nodes = [False for node in range(self.m_num_of_nodes)]
result = [[0 for column in range(self.m_num_of_nodes)]
for row in range(self.m_num_of_nodes)]
indx = 0
for i in range(self.m_num_of_nodes):
print(self.m_graph[i])
print(selected_nodes)
while(False in selected_nodes):
minimum = postitive_inf
start = 0
end = 0
for i in range(self.m_num_of_nodes):
if selected_nodes[i]:
for j in range(self.m_num_of_nodes):
if(not selected_nodes[j] and self.m_graph[i][j]>0):
if self.m_graph[i][j] < minimum:
minimum = self.m_graph[i][j]
start, end = i, j
selected_nodes[end] = True
result[start][end] = minimum
if minimum == postitive_inf:
result[start][end] = 0
print("(%d.) %d - %d: %d" % (indx, start, end, result[start][end]))
indx += 1
result[end][start] = result[start][end]
for i in range(len(result)):
for j in range(0+i, len(result)):
if result[i][j] != 0:
print("%d - %d: %d" % (i, j, result[i][j]))
example_graph = Graph(9)
example_graph.add_edge(0, 1, 4)
example_graph.add_edge(0, 2, 7)
example_graph.add_edge(1, 2, 11)
example_graph.add_edge(1, 3, 9)
example_graph.add_edge(1, 5, 20)
example_graph.add_edge(2, 5, 1)
example_graph.add_edge(3, 6, 6)
example_graph.add_edge(3, 4, 2)
example_graph.add_edge(4, 6, 10)
example_graph.add_edge(4, 8, 15)
example_graph.add_edge(4, 7, 5)
example_graph.add_edge(4, 5, 1)
example_graph.add_edge(5, 7, 3)
example_graph.add_edge(6, 8, 5)
example_graph.add_edge(7, 8, 12)
example_graph. _mst()

OUTPUT

[0, 4, 7, 0, 0, 0, 0, 0, 0]
[4, 0, 11, 9, 0, 20, 0, 0, 0]
[7, 11, 0, 0, 0, 1, 0, 0, 0]
[0, 9, 0, 0, 2, 0, 6, 0, 0]
[0, 0, 0, 2, 0, 1, 10, 5, 15]
[0, 20, 1, 0, 1, 0, 0, 3, 0]
[0, 0, 0, 6, 10, 0, 0, 0, 5]
[0, 0, 0, 0, 5, 3, 0, 0, 12]
[0, 0, 0, 0, 15, 0, 5, 12, 0]

[False, False, False, False, False, False, False, False, False]


(0.) 0 - 0: 0
(1.) 0 - 1: 4
(2.) 0 - 2: 7
(3.) 2 - 5: 1
(4.) 5 - 4: 1
(5.) 4 - 3: 2
(6.) 5 - 7: 3
(7.) 3 - 6: 6
(8.) 6 - 8: 5

0 - 1: 4
0 - 2: 7
2 - 5: 1
3 - 4: 2
3 - 6: 6
4 - 5: 1
5 - 7: 3
6 - 8: 5

Result:
Thus the program has been created, executed and the output is verified.
Ex. No: 9 Floyd’s Algorithm

Aim

To implement Floyd’s algorithm for the All-Pairs- Shortest-Paths problem.

Algorithm

1. Initialize the solution matrix same as the input graph matrix as a first step.
2. considering all vertices as an intermediate vertex. pick all vertices and updates all shortest
paths which include the picked vertex as an intermediate vertex in the shortest path.
3. When we pick vertex number k as an intermediate vertex, we already have considered
vertices {0, 1, 2, .. k-1} as intermediate vertices.
4. For every pair (i, j) of the source and destination vertices respectively, there are two possible
cases.
 k is not an intermediate vertex in shortest path from i to j. We keep the value of dist[i][j]
as it is.
 k is an intermediate vertex in 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]
Program

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 program has been created, executed and the output is verified.

Ex. No: 10 Warshall’s Algorithm

Aim

To compute the transitive closure of a given directed graph using Warshall's algorithm.

Algorithm

1. Create a boolean reach-ability matrix reach[V][V] .


2. The value reach[i][j] will be 1 if j is reachable from i, otherwise 0.
3. Instead of using arithmetic operations, use logical operations.
4. For arithmetic operation ‘+’, logical and ‘&&’ is used, and for a ‘-‘, logical or ‘||’ is used.

Program
from collections import defaultdict
class Graph:
def init (self, vertices):
self.V = vertices
def printSolution(self, reach):
print("Following matrix transitive closure of the given graph ")
for i in range(self.V):
for j in range(self.V):
if (i == j):
print("%7d\t" % (1),end=" ")
else:
print("%7d\t" %(reach[i][j]),end=" ")
print()
def transitiveClosure(self,graph):
reach =[i[:] for i in graph]
for k in range(self.V):
for i in range(self.V):
for j in range(self.V):
reach[i][j] = reach[i][j] or (reach[i][k] and reach[k][j])
self.printSolution(reach)
g= Graph(4)
graph = [[1, 1, 0, 1],
[0, 1, 1, 0],
[0, 0, 1, 1],
[0, 0, 0, 1]]
g.transitiveClosure(graph)

OUTPUT

Following matrix transitive closure of the given graph


1 1 1 1
0 1 1 1
0 0 1 1
0 0 0 1

Result:
Thus the program has been created, executed and the output is verified.

Ex. No: 11 State Space Search

Aim:
To implement N Queens problem using Backtracking.

Algorithm
1. Initialize an empty chessboard of size NxN.
2. Start with the leftmost column and place a queen in the first row of that column.
3. Move to the next column and place a queen in the first row of that column.
4. Repeat step 3 until either all N queens have been placed or it is impossible to place a queen
in the current column without violating the rules of the problem.
5. If all N queens have been placed, print the solution.
6. If it is not possible to place a queen in the current column without violating the rules of the
problem, backtrack to the previous column.
7. Remove the queen from the previous column and move it down one row.
8. Repeat steps 4-7.

Program

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
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,-1,-1),range(col,-1,-1)):
if board[i][j] == 1:
return False
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] ]
ifSolveNQUtil(board,0)==False:
print("SOlution does not exist")
return False
PrintSolution(board)
return True
SolveNQ()

OUTPUT
0010
1000
0001
0100
True

Result:

Thus the program has been created, executed and the output is verified.
Ex. No: 12 Travelling Salesman Problem

Aim

To find the optimal solution for the Traveling Salesperson problem and then solve the same
problem instance using any approximation algorithm and determine the error in the approximation.

Algorithm

1. Construct MST .
2. Determine an arbitrary vertex as the starting vertex of the MST.
3. Follow steps 3 to 5 till there are vertices that are not included in the MST
4. Find edges connecting any tree vertex with the fringe vertices.
5. Find the minimum among these edges.
6. Add the chosen edge to the MST if it does not form any cycle.
7. Return the MST and exit.

Program

from sys import maxsize


from itertools import permutations
V=4
def TravellingSalesmanProblem(graph, s):
vertex = []
for i in range(V):
if i != s:
vertex.append(i)
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
80

Result:

Thus the program has been created, executed and the output is verified.
Ex. No: 13 Merge Sort

Aim

To Implement Merge sort method to sort an array of elements and determine the time required to
sort. Repeat the experiment for different values of n, the number of elements in the list to be sorted
and plot a graph of the time taken versus n.

ALGORITHM:

1: The program first defines the merge_sort() function which implements the Merge sort algorithm.

2: It then defines a test_merge_sort() function which generates a list of n random numbers, sorts
the list using Merge sort, and measures the time required to sort the list.

3: Finally, the program tests the test_merge_sort() function for different values of n and plots a
graph of the time taken versus n using the Matplotlib library

Program:

import random

import time

import matplotlib.pyplot as plt

def merge_sort(arr):

if len(arr) > 1: mid = len(arr) // 2

left_half = arr[:mid]

right_half = arr[mid:]

merge_sort(left_half)

merge_sort(right_half)

i=j=k=0

while i < len(left_half) and j < len(right_half):

if left_half[i] < right_half[j]:

arr[k] = left_half[i]

i += 1

else:

arr[k] = right_half[j]
j += 1

k += 1

while i < len(left_half):

arr[k] = left_half[i]

i += 1

k += 1

while j < len(right_half):

arr[k] = right_half[j]

j += 1

k += 1

def test_merge_sort(n):

arr = [random.randint(1, 100)

for _ in range(n)]

start_time = time.time()

merge_sort(arr)

end_time = time.time()

return end_time - start_time

if __name__ == '__main__':

ns = [10, 100, 1000, 10000, 100000]

times = []

for n in ns:

t = test_merge_sort(n)

times.append(t)

print(f"Merge sort took {t:.6f} seconds to sort {n} elements.")

plt.plot(ns, times, 'o-')

plt.xlabel('Number of elements (n)')

plt.ylabel('Time taken (s)')

plt.title('Merge Sort')
plt.show()

Output

Merge sort took 0.000020 seconds to sort 10 elements.

Merge sort took 0.000249 seconds to sort 100 elements.

Merge sort took 0.003046 seconds to sort 1000 elements.

Merge sort took 0.021679 seconds to sort 10000 elements.

Merge sort took 0.283631 seconds to sort 100000 elements.

Result:

Thus the program has been created, executed and the output is verified.
Ex. No: 14 Quick Sort

Aim

To Implement Quick sort method to sort an array of elements and determine the time required
to sort. Repeat the experiment for different values of n, the number of elements in the list to be sorted
and plot a graph of the time taken versus n.

Algorithm

1: This program generates a list of random integers of size n, sorts the list using the quicksort
function, and measures the time required to sort the list.

2: It repeats this process num_repeats times and returns the average time taken.

3: The main function of the program tests the measure_time function for different values of n and
plots a graph of the time taken versus n.

4: The maximum value of n is set to max_n, and the step size between values of n is set to
step_size.

5: The program uses the built-in random and time modules to generate random integers and measure
time, respectively. Additionally, the quicksort function is implemented recursively and sorts the list in
ascending order

Program
import random
import time
def quicksort(arr):
if len(arr) <= 1:
return arr
pivot = arr[0]
left = []
right = []
for i in range(1, len(arr)):
if arr[i] < pivot:
left.append(arr[i])
else:
right.append(arr[i])
return quicksort(left) + [pivot] + quicksort(right)
def measure_time(n, num_repeats):
times = []
for _ in range(num_repeats):
arr = [random.randint(0, 1000000)
for _ in range(n)]
start_time = time.time()
quicksort(arr)
end_time = time.time()
times.append(end_time - start_time)
return sum(times) / len(times)
if __name__ == '__main__':

num_repeats = 10
max_n = 10000
step_size = 100
ns = range(0, max_n + step_size, step_size)
times = []
for n in ns:
if n == 0:
times.append(0)
else:
times.append(measure_time(n, num_repeats))
print(times)

Output:
[0, 0.00013625621795654297, 0.0006334543228149414, 0.000517892837524414,
0.0009247779846191407, 0.000916147232055664, 0.0010011672973632812,]

Result:

Thus the program has been created, executed and the output is verified.
Ex. No: 15 Randomized Algorithms for kth Smallest element

Aim
To implement randomized algorithms for finding the kth smallest number.
Algorithm
The partition() function takes an array arr, low index low, and high index high as input and partitions
the array around a randomly chosen pivot. It returns the index of the pivot element.
2. The randomized_select() function takes an array arr, low index low, high index high, and the value
of k as input and returns the kth smallest element in the array. It first selects a random pivot element
using random.randint() function and partitions the array using the partition() function. Then it
recursively calls itself on either the left or right partition depending on the position of the pivot
element.
3. In the main section, we define an array arr and the value of k. Then we calculate the length of the
array n and call the randomized_select() function on the array to find the kth smallest element.

Program
import random
# Function to partition the array around a pivot
def partition(arr, low, high):
i = low - 1
pivot = arr[high]
for j in range(low, high):
if arr[j] <= pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i+1], arr[high] = arr[high], arr[i+1]
return i+1
# Function to find the kth smallest number using randomized algorithm
def randomized_select(arr, low, high, k):
if low == high:
return arr[low]
pivot_index = random.randint(low, high)
arr[pivot_index], arr[high] = arr[high], arr[pivot_index]
index = partition(arr, low, high)
if k == index:
return arr[k]
elif k < index:
return randomized_select(arr, low, index-1, k)
else:
return randomized_select(arr, index+1, high, k)
# Testing the function
arr = [9, 4, 2, 7, 3, 6]
k=3
n = len(arr)
result = randomized_select(arr, 0, n-1, k-1)
print(f"The {k}th smallest number is: {result}")
OUTPUT:
The 3th smallest number is: 4

Result:

Thus the program has been created, executed and the output is verified.
EX.NO: 16 MATRIX MULTIPLICATION

Aim:
To write a C program to find the product of the two matrices.

Algorithm:-
Step 1: Start the program.
Step 2: Read the no. of rows and columns in matrix A and B.
Step 3: check if the row size of Matrix A and column size of Matrix B is equal (r1=c2),
goto step 4 otherwise goto Step 7
Step 4: Read the elements of two matrices one by one by using for loop.
Step 5: Multiply the elements of two matrices by using the condition
c[i][j]=a[i][k] * b[k][j]
Step 6: Print the resultant matrix.
Step 7: Print “Matrix Multiplication is not possible”
Step 8: Stop the program.

Program:-
#include <stdio.h>
#include<conio.h>
void main()
{
int a[3][3], b[3][3], c[3][3];
int r1,c1,r2,c2,i,j,k;
clrscr();
printf("\n Enter the no.of rows in matrx A:");
scanf("%d",&r1);
printf("\n Enter the no.of columns in matrx A:");
scanf("%d",&c1);
printf("\n Enter the no.of rows in matrx B:");
scanf("%d",&r2);
printf("\n Enter the no.of columns in matrx B:");
scanf("%d",&c2);
if(r1!=c2)
{
printf("\n Matrix multiplication is not possible..");
}
else
{
printf("Enter the elements in matrix A:\n");
for(i=0; i<r1; i++)
{
for(j=0; j<c1; j++)
{
scanf("%d", &a[i][j]);
}
}

printf("Enter the elements in matrix B:\n");


for(i=0; i<r2; i++)
{
for(j=0; j<c2; j++)
{
scanf("%d", &b[i][j]);
}
}
for(i=0; i<r1; i++)
{
for(j=0; j<c2; j++)
{
c[i][j]=0;
for(k=0;k<r1;k++)
{
c[i][j]=c[i][j]+a[i][k]*b[k][j];
}
}
}
printf("\nProduct of matrices:(A*B) = \n");
for(i=0; i<r1; i++)
{
for(j=0; j<c2; j++)
{
printf("%d ", c[i][j]);
}
printf("\n");
}
}
getch();
}

Output:-

Enter the no.of rows in matrx A: 2


Enter the no.of columns in matrx A: 2
Enter the no.of rows in matrx B:2
Enter the no.of columns in matrx B: 2
Enter the elements in matrix A:
2 2
2 2
Enter the elements in matrix B:
3 3
3 3
Product of matrices:(A*B) =

12 12

12 12

Result:
Thus the program has been created, executed and the output is verified.
EX.NO: 17 Finding Maximum and Minimum element in the given array

Aim:
To write a C program to find the product of the two matrices.

Algorithm

Step 1: Find the mid of the array.


Step 2: Find the maximum and minimum of the left subarray recursively.
Step 3: Find the maximum and minimum of the right subarray recursively.
Step 4: Compare the result of step 3 and step 4
Step 5: Return the minimum and maximum.

Program
#include<stdio.h>
#include<stdio.h>
int max, min;
int a[100];
void maxmin(int i, int j)
{
int max1, min1, mid;
if(i==j)
{
max = min = a[i];
}
else
{
if(i == j-1)
{
if(a[i] <a[j])
{
max = a[j];
min = a[i];
}
else
{
max = a[i];
min = a[j];
}
}
else
{
mid = (i+j)/2;
maxmin(i, mid);
max1 = max; min1 = min;
maxmin(mid+1, j);
if(max <max1)
max = max1;
if(min > min1)
min = min1;
}
}
}
int main ()
{
int i, num;
printf ("\nEnter the total number of numbers : ");
scanf ("%d",&num);
printf ("Enter the numbers : \n");
for (i=1;i<=num;i++)
scanf ("%d",&a[i]);

max = a[0];
min = a[0];
maxmin(1, num);
printf ("Minimum element in an array : %d\n", min);
printf ("Maximum element in an array : %d\n", max);
return 0;
}

output:-

Enter the total number of numbers : 5


Enter the numbers :
29
21
64
27
20
Minimum element in an array : 20
Maximum element in an array : 64

Result:
Thus the program has been created, executed and the output is verified.

You might also like