Cs3401-Algorithm Lab Manual
Cs3401-Algorithm Lab Manual
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
import matplotlib.pyplot
as plt import numpy as
np
import timeit import
math import random
def
linear_Search(list1,n,ke
y): 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(list
1)
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)'.f
ormat(n), globals=globals(),
number=10
0) for n in
ns]
plt.plot(ns,ts,'or')
degree=4
coeffs=np.polyfit(ns,ts,degr
ee) p=np.poly1d(coeffs)
plt.plot(ns,[p(n) for n in
ns],'-r')
ts=[timeit.timeit('contains(l
st,-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,de
gree) 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
Algorithm
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]<targ
et: satrt=mid+1
else:
return
mid
return -1
if name ==' main ':
nums=[2,12,15,17,27,2
9,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,de
gree) p=np.poly1d(coeffs)
plt.plot(ns,[p(n) for n in
ns],'-b')
OUTPUT
3
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
# Function
call
search(pat,
txt)
Output
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)'.f
ormat(n), globals=globals(),
number=
1) for n
in ns]
plt.plot(ns,ts,'or')
degree=4
coeffs=np.polyfit(ns,ts,de
gree) p=np.poly1d(coeffs)
plt.plot(ns,[p(n) for n in
ns],'-r')
OUTPUT
5
6
11
12
13
Heap Sort
Result:
Thus the program has been created, executed and the output is verified
Ex. No: 5 Graph Traversal using Breadth First
Search Aim:
Algorithm
# Constructor
self.graph = defaultdict(list)
self.graph[u].append(v)
[False] * (len(self.graph))
queue:
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)
Output
Result:
Thus the program has been created, executed and the output is verified.
Ex. No: 6 Graph Traversal using Depth First
Search
Aim
Algorithm
1. Create a recursive function that takes the index of the node and a visited array.
3. Traverse all the adjacent and unmarked nodes and call the recursive
function with the index of the adjacent node.
Program
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():
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(d
ist) 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:
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.prims_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]
(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.
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
Progra
m
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
03 5
7
20 4
6
31 5
0
53 0
2
Result:
Thus the program has been created, executed and the output is verified.
Ex. No: 10 Warshall’s
Algorithm
Aim
Algorithm
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(boa
rd) return True
SolveNQ()
OUTPUT
0010
1000
0001
0100
True
Result:
Thus the program has been created, executed and the output is verified
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
Result:
Thus the program has been created, executed and the output is verified.