Algorithms Laboratory Report 2024-2025
Algorithms Laboratory Report 2024-2025
NAME :
YEAR :
BRANCH :
REGISTER NUMBER :
Certified to be the Bonafide record of work done by the above student in FOURTH
SEMESTER in CS3401-ALGORITHMS LABORATORY during the year 2024-2025.
1
INDEX
2
10 24/04/25 Implementation of Transitive Closure 75
of directed graph using Warshall’s
Algorithm
11 24/04/25 Implementation of MinMax problem 80
using Divide and Conquer Technique
12a 26/04/25 Implementation of Merge Sort 85
Approximation Algorithm
15 08/05/25 Implementation of Randomized 107
Algorithm for finding the k th Smallest
Number
3
[Link] IMPLEMENTATION OF LINEAR SEARCH
DATE:27/02/25
AIM:
To implement linear search to determine the time required to search for an element. Repeat the
experiment for different values of n, the no of elements in the list to be searched and plot a graph of the
time taken versus n.
PSEUDOCODE:
4
PROGRAM:
import time
nbasicop=0
nbasicop+=1
if arr[index] == target:
return index,nbasicop
return -1,nbasicop
def measure_time(n,basicops):
start=[Link]()
index,nbasicop=linear_search(A,n)
end=[Link]()
[Link](nbasicop)
return end-start
n_values=[10,100,1000,10000,100000,1000000]
basicops=[]
print(n_values)
print(basicops)
print(times)
[Link](n_values,basicops,label="basicop",marker="o")
5
[Link]("N values")
[Link]("Basicops")
[Link](n,n,label="O(n) Plot")
[Link]()[Link](n_values,times)
[Link]("N values")
[Link]("Time taken(seconds)")
[Link]()
OUTPUT:
N Values:
Basic Operation:
Times:
6
7
RESULT:
Thus the implementation of linear search to determine the time required to search a element for the
different value of n , the number of element in the list to be searched and plot a graph of the time taken
versus n has been executed and verified successfully.
8
[Link]:2a IMPLEMENTATION OF ITERATIVE BINARY SEARCH
DATE:27/02/25
AIM:
To implement Iterative Binary Search to determine the time required to search for an element. Repeat the
experiment for different values of n, the no of elements in the list to be searched and plot a graph of the
time taken versus n.
PSEUDOCODE:
9
PROGRAM:
import time
low = 0
high = len(arr) - 1
basicops+=1
if arr[mid] == target:
return mid
low = mid + 1
else:
high = mid - 1
return -1,basicops
def measure_time1(n,basicops):
basicop=0
start=[Link]()
index,nbasicop=binary_search(A,0,n-1,n+1,basicop)
end=[Link]()
[Link](nbasicop)
return end-start
n_values=[10,100,1000,10000,100000,1000000]
10
basicops=[]
print("N Values:")
print(n_values)
print("Basic Operation:")
print(basicops)
print("Time Taken:")
print(times)
[Link](n_values,times,label="Times")
[Link]("N values")
import math
[Link](n_values,basicops,label='Basicop')
[Link](n_values,logvalue,label='lgn plot')
[Link]("n values")
[Link]()
[Link]()
11
OUTPUT:
N Values:
Basic Operation:
Time Taken:
12
RESULT:
Thus the implementation of Iterative Binary Search to determine the time required to search a element for
the different value of n , the number of element in the list to be searched and plot a graph of the time taken
versus n has been executed and verified successfully.
13
[Link]:2b IMPLEMENTATION OF RECURSIVE BINARY SEARCH
DATE:06/03/25
AIM:
To implement recursive binary search to determine the time required to search for an element. Repeat the
experiment for different values of n, the no of elements in the list to be searched and plot a graph of the
time taken versus n.
PSEUDOCODE:
14
PROGRAM:
import time
nbasicop=nbasicop+1
if arr[mid] == x:
return mid,nbasicop
else:
else:
return -1,nbasicop
def measure_time(n,basicop):
nbasicop=0
start=[Link]()
index,nbasicops=binary_search(a,0,len(a)-1,a[0],nbasicop)
end=[Link]()
[Link](nbasicops)
return end-start
import math
15
basicop=[]
time=[measure_time(n,basicop)for n in nv]
print(nv)
print(basicop)
print(time)
print(logvalue)
[Link](nv,time)
[Link]("N values")
[Link]("Time taken")
[Link](nv,basicop,label='Basicop')
[Link](nv,logvalue,label='Log')
[Link]("n values")
[Link]()
[Link]()
OUTPUT:
N Sizes:
Basic Operation:
Times:
16
[3.321928094887362, 6.643856189774724, 9.965784284662087, 13.287712379549449,
16.609640474436812, 19.931568569324174]
RESULT:
Thus the implementation of recursive binary search to determine the time required to search a element for
the different value of n ,the number of element in the list to be searched and plot a graph of the time taken
versus n has been executed and verified successfully.
17
[Link]:2c IMPLEMENTATION OF INTERPOLATION SEARCH
DATE:06/03/25
AIM:
To implement interpolation search to determine the time required to search for an element. Repeat the
experiment for different values of n, the no of elements in the list to be searched and plot a graph of the
time taken versus n.
PSEUDOCODE:
18
PROGRAM:
import time
nbasicop+=1
if arr[pos] == target:
return pos,nbasicop
else:
return -1,nbasicop
def measure_time(n,basicop):
nbasicop=0
start=[Link]()
x=len(a)-1
index,nbasicops=interpolate_search(a,0,len(a)-1,x,nbasicop)
end=[Link]()
[Link](nbasicops)
return end-start
import math
19
basicop=[]
time=[measure_time(n,basicop)for n in nv]
print(nv)
print(basicop)
print(time)
print(logvalue)
[Link](nv,time)
[Link]("N values")
[Link]("Time taken")
[Link](nv,basicop,label='Basicop')
[Link](nv,logvalue,label='Log')
[Link]("n values")
[Link]()
[Link]()
OUTPUT:
N Values
Basic Operation
[1, 1, 1, 1, 1, 1]
times:
20
[3.321928094887362, 6.643856189774724, 9.965784284662087, 13.287712379549449,
16.609640474436812, 19.931568569324174]
RESULT:
Thus the implementation of interpolation search to determine the time required to search a element for
the different value of n, the number of element in the list to be searched and plot a graph of the time taken
versus n has been executed and verified successfully.
21
[Link]:3a IMPLEMENTATION OF NAÏVE PATTERN MATCHING ALGORITHM
DATE:13/03/25
AIM:
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 the occurrences of pat[i] in txt[]. You may assume that n>m.
PSEUDOCODE:
22
PROGRAM:
[Link]('/content/drive')
import time
n = len(txt)
m = len(pat)
nbasicop = 0
occur = []
nbasicop+=1
j=0
nbasicop += 1
j += 1
if j == m:
nbasicop+=1
[Link](i)
return nbasicop
basicop=0
start = [Link]()
result = func(*args,basicop)
23
end = [Link]()
lengths = [1,3,5,8,10,13,15,18,20,23,25,28,30,33,35]
file_path = "/content/drive/MyDrive/[Link]"
lines = [Link]()
full_txt = lines[0].strip()
pat = lines[1].strip()
times = []
ops = []
valid_lengths = []
pat="bbb"
continue
txt = full_txt[:length]
valid_lengths.append(length)
[Link](nbasicop)
[Link](execution)
[Link](figsize=(12, 5))
[Link](1, 2, 1)
24
[Link](valid_lengths,times, marker='o', color='blue')
[Link](1, 2, 2)
[Link](valid_lengths,ops, color='green',label="Basicop")
[Link](n,n,label="O(n) Plot")
[Link]()
plt.tight_layout()
[Link]()
OUTPUT:
BEST CASE:
Basic Operations: [0, 1, 3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 33]
WORST CASE:
Basic Operations: [1, 3, 5, 8, 10, 13, 15, 18, 20, 23, 25, 28, 30, 33, 35]
25
BEST CASE:
WORST CASE:
RESULT:
Thus the program to print all the occurrences of pat[] in txt[] (Naïve Pattern Matching Algorithm) has been
executed and verified successfully.
26
[Link]:3b IMPLEMENTATION OF RABIN KARP PATTERN
AIM:
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 the occurrences of pat[i] in txt[]. You may assume that n>m.
PSEUDOCODE:
27
PROGRAM:
d = 256
m = len(pat)
n = len(txt)
p=t=0
h=1
h = (h * d) % q
for i in range(m):
p = (d * p + ord(pat[i])) % q
t = (d * t + ord(txt[i])) % q
nbasicop += 1
if p == t:
if txt[i:i + m] == pat:
nbasicop += 1
pass
if i < n-m:
nbasicop += 1
if t < 0:
t += q
nbasicop += 1
return nbasicop
28
def measure_time(func, *args):
basicop=0
start = [Link]()
result = func(*args,basicop)
end = [Link]()
lengths = [5,8,10,13,15,18,20,23,25,28,30,33,35,36,37]
file_path = "/content/drive/MyDrive/[Link]"
lines = [Link]()
full_txt = lines[0].strip()
pat = lines[1].strip()
times = []
ops = []
valid_lengths = []
pat="aaa"
continue
txt = full_txt[:length]
valid_lengths.append(length)
[Link](nbasicop)
[Link](execution)
29
print("Basic Operations:", ops)
[Link](figsize=(12, 5))
[Link](1, 2, 1)
[Link](1, 2, 2)
[Link](valid_lengths,ops, color='green',label="Basicop",marker="o")
j=len(pat)
print('NM value:',m)
[Link](n,m,label="O(nm) Plot")
#[Link]("log")
#[Link]("log")
[Link]()
plt.tight_layout()
[Link]()
30
OUTPUT:
WORST CASE:
Basic Operations: [3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 33, 34, 35]
N value: [15, 24, 30, 39, 45, 54, 60, 69, 75, 84, 90, 99, 105, 108, 111]
BEST CASE:
Basic Operations: [3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 33, 34, 35]
N value: [5, 8, 10, 13, 15, 18, 20, 23, 25, 28, 30, 33, 35, 36, 37]
31
RESULT:
Thus the program to print all the occurrences of pat[] in txt[] (Rabin Karp Pattern Matching Algorithm) has
been executed and verified successfully.
32
[Link]:3c IMPLEMENTATION OF KNUTH MORRIS PRATT PATTERN
AIM:
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 the occurrences of pat[i] in txt[]. You may assume that n>m.
PSEUDOCODE:
33
PROGRAM:
[Link]('/content/drive')
length = 0
i=1
nbasicop += 1
if pat[i] == pat[length]:
length += 1
lps[i] = length
i += 1
else:
if length != 0:
length = lps[length - 1]
else:
lps[i] = 0
i += 1
import time
m = len(pat)
n = len(txt)
34
lps, nbasicop = compute_lps_array(pat, nbasicop)
i=0
j=0
while i < n:
nbasicop += 1
if pat[j] == txt[i]:
i += 1
j += 1
if j == m:
j = lps[j - 1]
if j != 0:
j = lps[j - 1]
else:
i += 1
return nbasicop
basicop=0
start = [Link]()
result = func(*args,basicop)
end = [Link]()
lengths = [10,15,20,25,30,35,40,45,50,55,c0,c5,70]
file_path ="/content/drive/MyDrive/[Link]"
35
lines = [Link]()
full_txt = lines[0].strip()
times = []
ops = []
valid_lengths = []
continue
txt = full_txt[:length]
valid_lengths.append(length)
[Link](nbasicop)
[Link](execution)
[Link](figsize=(12, 5))
[Link](1, 2, 1)
[Link](1, 2, 2)
[Link](valid_lengths,ops, color='green',label="Basicop")
36
n=[i for i in range(10,70)]
j=len(pat)
print('N value:',n)
[Link](n,m,label="O(n) Plot",marker="s")
#[Link]("log")
#[Link]("log")
[Link]()
plt.tight_layout()
[Link]()
OUTPUT:
WORST CASE:
Basic Operations: [11, 16, 21, 26, 31, 36, 41, 46, 51, 56, 61, 66, 71]
37
BEST CASE:
Basic Operations: [11, 16, 21, 26, 31, 36, 41, 46, 51, 56, 61, 66, 71]
RESULT:
Thus the program to print all the occurrences of pat[] in txt[] (Knuth Morris Prattt Pattern Matching
Algorithm) has been executed and verified successfully.
38
[Link]:4a IMPLEMENTATION OF INSERTION SORT
DATE:27/03/25
AIM:
Sort a given set of elements using the Insertion Sort method 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 time taken vs n.
PSEUDOCODE:
39
PROGRAM:
import time
import random
def insertion_sort(arr):
nbasicop = 0
key = arr[i]
j=i-1
arr[j + 1] = arr[j]
j -= 1
nbasicop += 1
arr[j + 1] = key
nbasicop += 1
return nbasicop
def measure_time_and_ops(arr):
start_time = [Link]()
nbasicop = insertion_sort(arr)
end_time = [Link]()
times = []
basic_ops = []
for n in sizes:
40
arr = [[Link](1, 10000) for _ in range(n)] # Generate random list
[Link](time_taken)
basic_ops.append(nbasicop)
[Link]("Time (seconds)")
[Link]()
[Link](n,m,label="N(N-1)/2 Square")
[Link]()
[Link]()
OUTPUT:
41
RESULT:
Thus the program to sort the given set of elements using Insertion Sort method and determine the time
required to sort the elements for different values of n, the number of elements in the list to be sorted and
to plot a graph of the time taken vs n has been executed and verified successfully.
42
[Link]:4b IMPLEMENTATION OF HEAP SORT
DATE:27/03/25
AIM:
Sort a given set of elements using the Insertion Sort method 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 time taken vs n.
PSEUDOCODE:
43
PROGRAM:
import time
import random
largest = i
left = 2 * i + 1
right = 2 * i + 2
largest = left
nbasicop += 1
largest = right
nbasicop += 1
if largest != i:
nbasicop += 1
return nbasicop
def heap_sort(arr):
n = len(arr)
nbasicop = 0
44
arr[i], arr[0] = arr[0], arr[i]
nbasicop += 1
return nbasicop
start_time = [Link]()
nbasicop = sort_function(arr)
end_time = [Link]()
sizes = [10,50,100,500,1000,5000,10000,50000,100000,500000,1000000]
times_heap = []
ops_heap = []
for n in sizes:
times_heap.append(time_taken)
ops_heap.append(nbasicop)
print("Basicop:",ops_heap)
print("Times:",times_heap)
[Link](figsize=(12,6))
[Link](1,2,1)
[Link]("Time (seconds)")
45
[Link]()
[Link](1,2,2)
import numpy as np
[Link](sizes,logvalue,label="nlgn Plot")
[Link]()
[Link]()
OUTPUT:
Basicop: [50, 505, 1254, 9160, 20739, 133244, 290836, 1742990, 3737436, 21582966, 45665358]
46
RESULT:
Thus the program to sort the given set of elements using Insertion Sort method and determine the time
required to sort the elements for different values of n, the number of elements in the list to be sorted and
to plot a graph of the time taken vs n has been executed and verified successfully.
47
[Link] IMPLENTATION OF BREADTH FIRST SEARCH(BFS)
DATE:03/04/25
AIM:
To develop a program to implement graph traversal using Breadth First Search.
PSEUDOCODE:
48
PROGRAM:
import time as tm
import [Link] as plt
import random
import numpy as np
from collections import deque
def bfs(graph, start):
visited = {u: False for u in graph}
parent = {u: None for u in graph}
distance = {u: float('inf') for u in graph}
nbasicop = 0
queue = deque()
visited[start] = True
distance[start] = 0
[Link](start)
while queue:
u = [Link]()
nbasicop += 1
for v in graph[u]:
nbasicop += 1
if not visited[v]:
visited[v] = True
parent[v] = u
distance[v] = distance[u] + 1
[Link](v)
nbasicop += 1
return distance, parent, nbasicopdef measure_bfs_time(graph):
start_node = next(iter(graph))
start = [Link]()
_, _, ops = bfs(graph, start_node)
end = [Link]()
elapsed_time = end - start
return ops, elapsed_time
def generate_sparse_graph(n, edge_probability=0.2):
49
graph = {str(i): [] for i in range(n)}
for i in range(n):
for j in range(i + 1, n):
if [Link]() < edge_probability:
graph[str(i)].append(str(j))
graph[str(j)].append(str(i))
return graph
def generate_dense_graph(n):
graph = {str(i): [] for i in range(n)}
for i in range(n):
for j in range(n):
if i != j and [Link]() < 0.9: # 90% edge probability for dense
graph[str(i)].append(str(j))
return graph
ns = list(range(2,500, 10))
sparse_times = []
sparse_ops = []
dense_times = []
dense_ops = []
for n in ns:
sparse_graph = generate_sparse_graph(n)
sparse_ops_count, sparse_elapsed_time = measure_bfs_time(sparse_graph)
sparse_times.append(sparse_elapsed_time)
sparse_ops.append(sparse_ops_count)
dense_graph = generate_dense_graph(n)
dense_ops_count, dense_elapsed_time = measure_bfs_time(dense_graph)
dense_times.append(dense_elapsed_time)
dense_ops.append(dense_ops_count)
time={dense_elapsed_time:.6f}s, ops={dense_ops_count}")
print("Basicop(sparse):",sparse_ops)
print("Basicop(dense):",dense_ops)
print("Times(sparse)",sparse_times)
print("Times(dense)",dense_times)
[Link](figsize=(12, 5))
50
[Link](1, 2, 1)
[Link](ns, sparse_times, color='blue', label="Sparse Graph")
[Link](ns, dense_times, color='green', label="Dense Graph")
[Link]("BFS: n vs Time")
[Link]("Number of Vertices (n)")
[Link]("Time (seconds)")
[Link]()
[Link](1, 2, 2)
[Link](ns, sparse_ops, color='blue', label="Sparse Graph")
n=[i for i in range(2,500)]
m=[(i*i-i)/2 for i in range(2,500)]
[Link](n,m,label='V(v-1)/2 Plot')
#[Link](ns, dense_ops, marker='s', color='green', label="Dense Graph")
[Link]("BFS: n vs Basic Operations")
[Link]("Number of Vertices (n)")
[Link]("Basic Operations (nbasicop)")
[Link]()
plt.tight_layout()
[Link]()
OUTPUT:
Basicop(sparse): [1, 49, 129, 259, 437, 633, 911, 1203, 1527, 1907, 2313, 2683, 3279, 3785, 4395, 4899,
5615, 6235, 6881, 7691, 8543, 9323, 10085, 11219, 12151, 13199, 14229, 15575, 16407, 17251, 19173,
20137, 21415, 22751, 23763, 25419, 26807, 28419, 29609, 31397, 33485, 34589, 36111, 38081, 39893,
41411, 42647, 45415, 47457, 49479]
Basicop(dense): [5, 141, 462, 972, 1652, 2495, 3550, 4742, 6148, 7702, 9491, 11396, 13566, 15809,
18236, 21098, 23816, 26919, 30012, 33268, 36895, 40734, 44570, 48764, 52961, 57322, 62094, 66789,
71866, 77138, 82458, 87866, 93668, 99582, 105613, 111907, 118318, 124948, 131738, 138888, 146035,
153087, 160988, 168287, 176201, 184218, 192408, 201064, 209684, 218525]
51
RESULT:
Thus the program to implement graph traversal using Breadth First Search has been executed and verified
successfully.
52
[Link] IMPLEMENTATION OF DEPTH FIRST SEARCH(DFS)
DATE:03/04/25
AIM:
PSEUDOCODE:
53
PROGRAM:
import time as tm
import random
import numpy as np
def dfs(graph,nbasicop):
discovery_time = {}
finish_time = {}
for u in graph:
nbasicop+=1
discovery_time[u] = nbasicop
visited[u] = True
for v in graph[u]:
nbasicop += 1
if not visited[v]:
parent[v] = u
finish_time[u] = nbasicop
54
return nbasicop
def measure_time(graph):
nbasicop=0
start = [Link]()
_, _, _, ops = dfs(graph,nbasicop)
end = [Link]()
for i in range(n):
graph[str(i)].append(str(j))
graph[str(j)].append(str(i))
return graph
def generate_dense_graph(n):
np.fill_diagonal(matrix, 0)
return matrix
def adjacency_matrix_to_list(matrix):
n = [Link][0]
for i in range(n):
for j in range(n):
55
if matrix[i][j] == 1:
graph[str(i)].append(str(j))
return graph
ns = list(range(1,100, 10))
sparse_times = []
sparse_ops = []
dense_times = []
dense_ops = []
for n in ns:
sparse_graph = generate_sparse_graph(n)
sparse_times.append(sparse_elapsed_time)
sparse_ops.append(sparse_ops_count)
dense_matrix = generate_dense_graph(n)
dense_graph = adjacency_matrix_to_list(dense_matrix)
dense_times.append(dense_elapsed_time)
dense_ops.append(dense_ops_count)
[Link](figsize=(14, 6))
print("Basicop(sparse):",sparse_ops)
print("Basicop(dense):",dense_ops)
print("Times(sparse)",sparse_times)
print("Times(dense)",dense_times)
[Link](1, 2, 1)
56
[Link](ns, dense_times, color='green', label="Dense Graph")
[Link]("n vs Time")
[Link]("Time (seconds)")
[Link]()
[Link](1, 2, 2)
[Link](n,o,label='N(N-1)/2 Plot')
[Link]()
plt.tight_layout()
[Link]("Basic Operations")
[Link]()
[Link]()
57
OUTPUT:
Basicop(sparse): [1, 33, 115, 207, 377, 497, 809, 1103, 1383, 1693]
Basicop(dense): [1, 59, 238, 509, 912, 1314, 1881, 2467, 3285, 4104]Times(sparse)
[1.0251998901367188e-05, 2.3603439331054688e-05, 4.291534423828125e-05, 6.151199340820312e-
05, 0.00010585784912109375, 0.00013518333435058594, 0.00017714500427246094,
0.0004279613494873047, 0.0004086494445800781, 0.0006501674652099609]
58
RESULT:
Thus the program to implement graph traversal using Depth First Search has been executed and verified
successfully.
59
[Link] IMPLEMENTATION OF DIJKSTRA’S ALGORITHM
DATE:17/04/25
AIM:
From the given vertex in a weighted connected graph, develop a program to find the shortest paths to other
vertices using the Dijkstra’s Algorithm.
PSEUDOCODE:
60
PROGRAM:
import time
import numpy as np
import heapq
n = len(graph)
visited = [False] * n
dist = [float('inf')] * n
dist[start] = 0
basicop = 0
while heap:
d, u = [Link](heap)
basicop += 1
if visited[u]:
continue
visited[u] = True
basicop += 1
for v in range(n):
basicop += 1
61
basicop += 1
return basicop
start = [Link]()
basicop = func(*args)
end = [Link]()
def generate_weighted_connected_matrix(n):
for i in range(n):
return matrix
times = []
basicops = []
g = generate_weighted_connected_matrix(size)
t, basicop = measure_time_and_basicop(dijkstra_matrix, g, 0)
[Link](t)
62
[Link](basicop)
[Link](figsize=(12, 6))
[Link](1, 2, 1)
[Link]("Time (seconds)")
[Link](1, 2, 2)
[Link]()
plt.tight_layout()
[Link]()
OUTPUT:
Basic Operation: [131, 997, 2673, 5165, 8439, 12525, 17465, 23135, 29637, 36967, 45027, 53969, 63617,
74197, 85489, 97601, 110565, 124209, 138729, 154073, 170145, 187011, 204857, 223281, 242587]
63
RESULT:
Thus the program to find the shortest paths to other vertices from a given vertex in a weighted connected
graph using Dijkstra’s Agorithm has been executed and verified successfully.
64
[Link] IMPLEMENTATION OF PRIM’S ALGORITHM
DATE:17/04/25
AIM:
To find the minimum cost spanning tree of a given undirected graph using Prim’s Algorithm.
PSEUDOCODE:
65
PROGRAM:
import time
import numpy as np
import heapq
def prim_matrix(graph,basicop):
n = len(graph)
visited = [False] * n
total_cost = 0
while min_heap:
cost, u = [Link](min_heap)
if visited[u]:
continue
visited[u] = True
total_cost += cost
for v in range(n):
return basicop
basicop=0
start = [Link]()
66
basicop = func(*args,basicop)
end = [Link]()
def generate_weighted_connected_matrix(n):
for i in range(n):
if [Link]() < 1:
return matrix
sizes = [1,2,3,4,5,6,7,8,9,10,20,30,40,50,60,70,90,100]
times = []
basicops = []
g = generate_weighted_connected_matrix(size)
t, basicop = measure_time_and_basicop(prim_matrix, g)
[Link](t)
[Link](basicop)
print("Basicop:",basicops)
print("Times:",times)
[Link](figsize=(12, 6))
67
[Link](1, 2, 1)
[Link]("Time (seconds)")
[Link](1, 2, 2)
[Link]()
plt.tight_layout()
[Link]()
OUTPUT:
Basicop: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 400, 900, 1600, 2500, 3600, 4900, 8100, 10000]
68
RESULT:
Thus the program to find the minimum cost spanning tree of a given undirected graph using Prim’s
Algorithm has been executed and verified successfully.
69
[Link] IMPLENTATION OF FLOYD WARSHALL’S ALGORITHM
DATE:24/04/25
AIM:
PSEUDOCODE:
70
PROGRAM:
import time
import numpy as np
def floyd_warshall(graph):
n = len(graph)
basicop = 0
for i in range(n):
for j in range(n):
if i == j:
dist[i][j] = 0
dist[i][j] = graph[i][j]
for k in range(n):
for i in range(n):
for j in range(n):
basicop += 1
#basicop += 1
return basicop
def measure_time_and_basicop(func,*args):
basicop=0
start = [Link]()
71
basicop = func(*args)
end = [Link]()
def generate_weighted_connected_matrix(n):
for i in range(n):
return matrix
sizes = [1,5,10,50,100,500]
times = []
basicops = []
g = generate_weighted_connected_matrix(size)
t, basicop = measure_time_and_basicop(floyd_warshall, g)
[Link](t)
[Link](basicop)
print('Basic Operation')
print(basicops)
print('Time')
72
print(times)
[Link](figsize=(12, 6))
[Link](1, 2, 1)
[Link]("Time (seconds)")
[Link](1, 2, 2)
[Link]('log')
[Link]('log')
[Link]()
plt.tight_layout()
[Link]()
OUTPUT:
Basic Operation
Time:
73
RESULT:
Thus the program to implement Floyd’s Algorithm for the All-Pairs-Shortest-PathsProblem has been
executed and verified successfully.
74
[Link] IMPLEMENTATION OF TRANSITIVE CLOSURE OF
AIM:
To compute the transitive closure of a given directed graph using the Warshall’s Algorithm.
PSEUDOCODE:
75
PROGRAM:
import time
import numpy as np
def transitive_closure_floyd_warshall(W,nbasicop):
n = len(W)
for k in range(n):
for i in range(n):
for j in range(n):
nbasicop+=1
return nbasicop
def measure_time_and_basicop(func,*args):
basicop=0
start = [Link]()
basicop = func(*args,basicop)
end = [Link]()
def generate_weighted_connected_matrix(n):
for i in range(n):
76
for j in range(i + 2, n):
return matrix
sizes = [1,5,10,50,100,500]
times = []
basicops = []
g = generate_weighted_connected_matrix(size)
t, basicop = measure_time_and_basicop(transitive_closure_floyd_warshall, g)
[Link](t)
[Link](basicop)
[Link](figsize=(12, 6))
[Link](1, 2, 1)
[Link]("Time (seconds)")
[Link](1, 2, 2)
print("Basic Operation:")
77
print(basicops)
print("Times:")
print(times)
[Link]()
[Link]("log")
[Link]("log")
plt.tight_layout()
[Link]()
OUTPUT:
Basic Operation:
Times:
78
RESULT:
Thus the program to compute the transitive closure of a given directed graph using Warshall’s Algorithm
has been executed and verified successfully.
79
[Link] IMPLEMENTATION OF FINDING MINIMUM AND MAXIMUM
AIM:
To develop a program to find out the maximum and minimum numbers in a given list of n numbers using
the divide and conquer technique.
PSEUDOCODE:
80
PROGRAM:
import time
import random
if i == j:
elif i == j - 1:
nbasicop += 1
else:
else:
mid = (i + j) // 2
nbasicop+= 2
def measure_time_and_ops(arr):
nbasicop = 0
start_time = [Link]()
end_time = [Link]()
81
def build_best_case(arr):
if not arr:
return []
mid=len(arr)//2
result = [arr[mid]]
[Link](build_best_case(arr[:mid]))
[Link](build_best_case(arr[mid+1:]))
return result
ns = list(range(10,10000, 50))
times = []
ops = []
for n in ns:
ar=build_best_case(arr)
t, op = measure_time_and_ops(ar)
[Link](t)
[Link](op)
[Link](figsize=(12, 5))
[Link](1, 2, 1)
[Link]("Time vs n")
[Link]("Time (seconds)")
[Link](1, 2, 2)
82
[Link]("Performance of findminmax in terms of no of basicop")
[Link](n,m,label='3n/2 -2 plot')
#[Link]('log')
#[Link]('log')
print('Basic Operation:',ops)
print("Times:",times)
[Link]()
plt.tight_layout()
[Link]()
OUTPUT:
BEST CASE:
Basic Operation: [14, 90, 172, 254, 336, 390, 490, 590, 664, 714, 764, 862, 962, 1062, 1162, 1262, 1320,
1370, 1420, 1470, 1520, 1606, 1706, 1806, 1906, 2006, 2106, 2206, 2306, 2406, 2506, 2582, 2632, 2682,
2732, 2782, 2832, 2882, 2932, 2982, 3032, 3094, 3194, 3294, 3394, 3494, 3594, 3694, 3794, 3894, 3994,
4094, 4194, 4294, 4394, 4494, 4594, 4694, 4794, 4894, 4994, 5094…..]
83
WORST CASE:
Basic Operation: [14, 90, 172, 254, 336, 390, 490, 590, 664, 714, 764, 862, 962, 1062, 1162, 1262, 1320,
1370, 1420, 1470, 1520, 1606, 1706, 1806, 1906, 2006, 2106, 2206, 2306, 2406, 2506, 2582, 2632, 2682,
2732, 2782, 2832, 2882, 2932, 2982, 3032, 3094, 3194, 3294, 3394, 3494, 3594, 36……]
RESULT:
Thus the program to find out the maximum and minimum numbers in a given list of n numbers using divide
and conquer technique has been executed and verified successfully.
84
[Link]:12a IMPLEMENTATION OF MERGE SORT
DATE:26/04/25
AIM:
To implement Merge 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.
PSEUDOCODE:
85
PROGRAM:
import time
import random
nbasicop = 0
global nbasicop
n1 = mid - left + 1
n2 = right - mid
L = arr[left:mid + 1]
R = arr[mid + 1:right + 1]
i=j=0
k = left
nbasicop += 1 # Comparison
arr[k] = L[i]
i += 1
else:
arr[k] = R[j]
j += 1
k += 1
arr[k] = L[i]
i += 1
86
k += 1
arr[k] = R[j]
j += 1
k += 1
def measure_time_and_ops(arr):
global nbasicop
nbasicop = 0
start_time = [Link]()
merge_sort(arr, 0, len(arr) - 1)
end_time = [Link]()
def build_best_case(arr):
if not arr:
return []
mid=len(arr)//2
result = [arr[mid]]
[Link](build_best_case(arr[:mid]))
[Link](build_best_case(arr[mid+1:]))
87
return result
ns =[10,100,1000,10000]
times = []
ops = []
for n in ns:
ar = [Link](range(1, 100000), n)
arr=build_best_case(ar)
t, op = measure_time_and_ops(arr[:])
[Link](t)
[Link](op)
[Link](figsize=(12, 5))
[Link](1, 2, 1)
[Link]("Time (seconds)")
[Link]()
[Link](1, 2, 2)
print("Basic Operation")
print(ops)
88
import math
[Link](n,m,label='nlgn Plot')
[Link]()
plt.tight_layout()
[Link]()
OUTPUT:
Basic Operation
Times:
WORST CASE:
Basic Operation
Times:
89
RESULT:
Thus the program to implement Merge Sort methods to sort an array of elements and determine the time
required to sort and replace the experiment for different values of n, the number of elements in the list to
be sorted and a plot a graph for the time taken vs n has been executed and verified successfully.
90
[Link]:12b IMPLEMENTATION OF ǪUICK SORT
DATE:26/04/25
AIM:
To implement Ǫuick Sort to sort an array of elements and determine the time required 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.
PSEUDOCODE:
91
PROGRAM:
import time
import math
import random
def partition(arr,low,high,nbasicop):
pivot=arr[high]
i=low-1
for j in range(low,high):
nbasicop+=1
if arr[j]<=pivot:
i+=1
arr[i],arr[j]=arr[j],arr[i]
nbasicop+=1
arr[i+1],arr[high]=arr[high],arr[i+1]
nbasicop+=1
return i+1,nbasicop
def quick_sort(arr,low,high,nbasicop):
if low<high:
pi,nbasicop=partition(arr,low,high,nbasicop)
nbasicop=quick_sort(arr,low,pi-1,nbasicop)
nbasicop=quick_sort(arr,pi+1,high,nbasicop)
return nbasicop
def measure_time(arr):
nbasicop=0
92
start_time=[Link]()
nbasicop=quick_sort(arr,0,len(arr)-1,nbasicop)
end_time=[Link]()
return end_time-start_time,nbasicop
def build_best_case(arr):
if not arr:
return []
mid=len(arr)//2
result=[arr[mid]]
[Link](build_best_case(arr[:mid]))
[Link](build_best_case(arr[mid+1:]))
return result
ns=list(range(10,1000))
times=[]
basicops=[]
for n in ns:
arr=[Link](range(1,1000),n)
ar=build_best_case(arr[:])
t,nbasicop=measure_time(ar)
[Link](t)
[Link](nbasicop)
print("Basicop:",basicops)
print("Times:",times)
93
[Link](figsize=(12,6))
[Link](1,2,1)
[Link](ns,times,color='red')
[Link]("Time (seconds)")
[Link](1,2,2)
[Link](n,m,label="n*n plot")
[Link](ns,basicops,label='Basic Operations',color='purple')
[Link]()
[Link]()
OUTPUT:
WORST CASE:
Basic Operations:
[38, 44, 48, 51, 58, 61, 66, 73, 81, 88, 93, 101, 108, 115, 129, 134, 137, 141, 156, 164, 171, 175, 186, 192,
197, 205, 213, 222, 240, 248, 261, 267, 275, 284, 301, 309, 316, 324, 334, 349, 356, 362, 372, 376, 405,
410, 426, 442, 440, 449, 468, 476, 489, 494, 510, 522, 544, 551, 566, 572, 577, 586, 599, 608, 616, 626,
637, 656, 694, 703, 719, 733, 767, 774, 802, 811, 819, 829, 849, 867, 907, 916, 939, 947, 954, 963, 982,
993, 1020, 1036]
Times:
94
BEST CASE:
Basicop: [43, 66, 47, 58, 69, 80, 70, 84, 109, 105, 116, 134, 191, 129, 137, 150, 139, 207, 166, 184, 176,
212, 235, 292, 240, 227, 229, 247, 253, 250, 424, 446, 329, 296, 333, 308, 327, 390, 372, 418, 407, 474,
397, 426, 361, 415, 456, 512, 457, 536…..]
RESULT:
Thus the program to implement quick sort methods to sort an array of elements and determine the
time taken to sort and report the experiment for different values of n,the number of elements in the list to
be sorted and to plot a graph for the time taken vs n has been executed and verified successfully.
95
[Link] IMPLENTATION OF N ǪUEENS PROBLEM USING BACKTRACKING
DATE:03/05/25
AIM:
PSEUDOCODE:
96
PROGRAM:
import time
basic_op = 0
backtrack_count=0
x = []
basic_op += 1
return False
return True
global x,backtrack_count
if Place(k, i):
x[k] = i
if k < n:
backtrack_count+=1
NQueens(k + 1, n)
return basic_op,backtrack_count
def measure_time(n):
global x, basic_op
x = [0] * (n + 1)
97
basic_op = 0
start = [Link]()
NQueens(1, n)
end = [Link]()
ns = list(range(4,12))
times = []
ops = []
for n in ns:
t, op,bt = measure_time(n)
[Link](t)
[Link](op)
print("N Value:",n)
print("Basicop:",op)
print("Backtrack:",bt)
[Link](figsize=(12, 5))
[Link](1, 2, 1)
[Link]('Time (seconds)')
[Link](1, 2, 2)
98
[Link]('Number of Basic Operations')
print("Basic Operation")
print(ops)
import math
[Link](n,m,label='Factorial Plot')
[Link]()
plt.tight_layout()
[Link]()
OUTPUT:
N Value: 4
Basicop: 84
Backtrack: 14
N Value: 5
Basicop: 405
Backtrack: 57
N Value: 6
Basicop: 2016
Backtrack: 205
N Value: 7
Basicop: 9297
Backtrack: 716
N Value: 8
Basicop: 46752
99
Backtrack: 2680
N Value: 9
Basicop: 243009
Backtrack: 10721
N Value: 10
Basicop: 1297558
Backtrack: 45535
N Value: 11
Basicop: 7416541
Backtrack: 209780
Basic Operation
RESULT:
Thus the program to implement N Ǫueens problem using Backtracking has been executed and
verified successfully.
100
[Link] IMPLEMENTATION OF TRAVELING SALESPERSON
AIM:
To implement any scheme to find the optimal solution for the traveling salesperson problem and to
solve the same problem instance using any approximation algorithm and determine the error in the
approximation.
PSEUDOCODE:
101
PROGRAM:
import time
import heapq
import random
import math
start = [Link]()
end = [Link]()
for i in range(n):
matrix[i][j] = weight
matrix[j][i] = weight
return matrix
def prim_mst(graph):
n = len(graph)
in_mst = [False] * n
parent = [-1] * n
102
key = [float('inf')] * n
key[0] = 0
nbasicop = 0
while pq:
k, u = [Link](pq)
if in_mst[u]:
continue
nbasicop += 1
in_mst[u] = True
for v in range(n):
key[v] = graph[u][v]
parent[v] = u
def parent_to_adjlist(parent):
n = len(parent)
u = parent[v]
adj_list[u].append(v)
adj_list[v].append(u)
return adj_list
103
visited = set()
tour = []
def dfs(u):
[Link](u)
[Link](u)
for v in adj_list[u]:
if v not in visited:
dfs(v)
dfs(start)
return tour
cost = 0
return cost
def exact_tsp_solver(graph):
n = len(graph)
if n > 10:
min_cost = float('inf')
best_path = []
104
if cost < min_cost:
min_cost = cost
best_path = tour
adj_list = parent_to_adjlist(parent)
tsp_tour = preorder_traversal(adj_list)
approx_error = None
if optimal_cost:
n_values = list(range(3,10))
[Link](42)
approximation_costs = []
optimal_costs = []
basicops = []
times = []
approximation_errors = []
for n in n_values:
random_matrix = generate_random_distance_matrix(n)
optimal_cost = None
if n <= 10:
105
(optimal_cost, optimal_tour), exact_time = measure_time(exact_tsp_solver, random_matrix)
else:
[Link](nbasicop)
[Link](mst_time)
approximation_costs.append(tsp_cost)
optimal_costs.append(optimal_cost)
approximation_errors.append(approx_error)
OUTPUT:
Running for n = 3
Exact TSP Cost: 101
Approximation Path (Tour): [0, 2, 1, 0]
Approximation Cost: 101
Running for n = 4
Exact TSP Cost: 115
Approximation Path (Tour): [0, 3, 1, 2, 0]
Approximation Cost: 115
Running for n = 5
Exact TSP Cost: 113
Approximation Path (Tour): [0, 1, 2, 3, 4, 0]
106
Approximation Cost: 113
Running for n = 6
Exact TSP Cost: 211
Approximation Path (Tour): [0, 1, 3, 4, 2, 5, 0]
Approximation Cost: 211
Running for n = 7
Exact TSP Cost: 133
Approximation Path (Tour): [0, 2, 4, 1, 3, 5, 6, 0]
Approximation Cost: 178
Running for n = 8
Exact TSP Cost: 150
Approximation Path (Tour): [0, 4, 2, 5, 6, 3, 7, 1, 0]
Approximation Cost: 250
Running for n = 9
Exact TSP Cost: 200
Approximation Path (Tour): [0, 1, 3, 6, 5, 8, 4, 2, 7, 0]
Approximation Cost: 293
Basic Operations (Prim's MST): [3, 4, 5, 6, 7, 8, 9]
Time Taken (MST + Approx): [4.029273986816406e-05, 1.1682510375976562e-05, 1.3828277587890625e-
05, 1.4066696166992188e-05, 2.1696090698242188e-05, 3.981590270996094e-05,
4.696846008300781e-05]
Approximation cost: [101, 115, 113, 211, 178, 250, 293]
Approximation error: [0.0, 0.0, 0.0, 0.0, 33.83458646616541, 66.66666666666666, 46.5]
RESULT:
Thus the program to implement any scheme to find the optimal solution for the traveling salesperson
problem and to solve the same problem instance using any approximation algorithm and determination of
error in the approximation has been executed and verified successfully.
107
[Link] IMPLEMENTATION OF RANDOMIZED ALGORITHM FOR
AIM:
PSEUDOCODE:
108
PROGRAM:
import random
import time
nbasicop = 0
global nbasicop
pivot = arr[high]
i = low - 1
i += 1
return i + 1
if low == high:
return arr[low]
if k == count:
return arr[pivot_index]
109
return randomized_quickselect(arr, low, pivot_index - 1, k)
else:
times=[]
basicops=[]
for n in ns:
k = [Link](1, n)
nbasicop = 0
start = [Link]()
end = [Link]()
print("n:",n)
print("Times:",elapsed)
print("nbasicop:",nbasicop)
[Link](elapsed)
[Link](nbasicop)
print("Basicop:",basicops)
print("Times:",times)
OUTPUT:
n: 1000
Times: 0.0005917549133300781
nbasicop: 2523
n: 2000
Times: 0.001584768295288086
nbasicop: 6893
n: 5000
Times: 0.004640340805053711
110
nbasicop: 21854
n: 10000
Times: 0.006039619445800781
nbasicop: 26545
n: 20000
Times: 0.011452198028564453
nbasicop: 51630
n: 50000
Times: 0.03369450569152832
nbasicop: 115951
n: 100000
Times: 0.08425402641296387
nbasicop: 218466
Basicop: [2523, 6893, 21854, 26545, 51630, 115951, 218466]
Times: [0.0005917549133300781, 0.001584768295288086, 0.004640340805053711,
0.006039619445800781, 0.011452198028564453, 0.03369450569152832,
0.08425402641296387]
RESULT:
Thus the program to implement randomized algorithms for finding the Kth smallest number has been
executed and verified successfully.
111