0% found this document useful (0 votes)
39 views

Cs3401 Lab Manual

Uploaded by

govindarajupdf
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)
39 views

Cs3401 Lab Manual

Uploaded by

govindarajupdf
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/ 39

ESTO.

2001

PRATHYUSHA ENGINEERING COLLEGE


DEPARTMENT OF COMPUTER SCIENCE ANQENGINEERING

0V
LAB MANUAL
for
CS3401-ALGORifflMS LABORATORY

(Regulation 2021, IV Semester)


(Even Semester)

J\.CADEMIC YEAR: 2023 - 2024

PREPARED BY
S.FAMITHA,
Assistant Professor / CSE
1. SEARCHING AND SORTING ALGORITHMS

a. 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.

Aim:
Write a Python program to search an element using Linear search method and
plot a graph of the time taken versus n.

Algorithm:
1. Start from the first element of the list and compare it wi e Search element.
2. If the Search element is found, return the index oft ement in the list.
3. If the Search element is not found, move to the ne t element and repeat the
comparison.
4. Repeat this process until either the Se· li element is found or the end of the
list is reached.
5. If the Search element is not fou in the list, return -1 to indicate that the
element is not present.
The algorithm to plot a graph of the time taken versus n for linear search is as
follows:

1. Initializ an array time_taken to store the time taken to perform linear


s ar h for different values of n.
2. For i in the range 1 to n, do the following:
a. Generate a list of i elements.
b. Record the start time start_time just before performing linear search
on the list.
c. Perform linear search on the list.
d. Record the end time end_time just after performing linear search on
the list.
e. Calculate the time taken as time_taken[i] ::: end_time - start_time.
3. Plot a graph with non the x-axis and time_taken on the y-axis.

1
Program:
import matplotlib.pyplot as
pit def linear_search(arr, x):
for i in range(len(arr)):
if arr[i] :::::: x:
return i
return -1
arr ::: [ 2, 3, 4, 10, 40 ]
X::: 50
# Function call
result:::linear_search(arr, x)
if resu It :::::: -1:
print("Element is not present in array")
else:
print("Element is present at index", result)
n::: [10, 20, 50, 100, 200, 500, 1000]
time:::[0.0001, 0.0003, 0.0008, 0.0015, .0<)30, 0.0075, 0.0150]
plt.plot(n, time)
plt.xlabel('Number of Elements')
plt.ylabel('Time Taken')
plt.title('Time Complexity of Ijn, ar Search')
pit.show()

Output:
□ X

Time Complexity of Linear Search

).014

1.012

1.010

1.008

1.006

).004

1.002

1.000
0 200 400 600 800 1000
Number of Flements

2
b. 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.

Aim:
Write a Python program to earch an element using Binary search method and
plot a graph of the time taken versus n.

Algorithm:
1. Given a sorted list of elements, start by finding the middle element.
2. Compare the search element with the middle element.
3. If the search element is equal to the middle element,
index of the middle
return element.
4. If the search element is less than the middle element repeat the process on the left
half of the list (before the middle element)
5. If the search element is greater than the re element, repeat the process on the
right half of the list (after the middle e1ement).
6. Repeat steps 1 and 2 until either the earch element is found or the list has been
fully searched and the search I ent is not present.
7. If the search element is not found, return -1 to indicate that the element is
not present in the list.
Note: The list must be so d in ascending or descending order for binary search to work.

The algorithm to plot a graph of the time taken versus n for linear search is as follows:

1. Initializ an array time_taken to store the time taken to perform binary search for
different values of n.
2. For i in the range 1 to n, do the following:
a. Generate a sorted list of i elements.
b. Record the start time start_time just before performing binary search on
the list.
c. Perform binary search on the list.
d. Record the end time end_time just after performing binary search on the list.
e. Calculate the time taken as time_taken[i] ::: end_time - start_time.
3. Plot a graph with non the x-axis and time_taken on the y-axis.

3
Program:
def binary_search(arr, x):
low::: 0
high ::: len(arr) - 1
mid:::0
while low <::: high: mid:::
(high+ low)// 2
# Check if x is present at mid
if arr[mid] < x:
low ::: mid + 1
# If x is greater, ignore left half
elif arr[mid] > x:
high ::: mid - 1

# If x is smaller, ignore right half


else:
return mid
# If we reach here, then the element was o
return -1
# Test array
arr ::: [2, 3, 4, 10, 40]
X::: 10
# Function call
result ::: binary_se h()rr, x)
if result !:::-1:
print("Element is present at index", str(result))
else:
print("Element is not present in array")
import matplotlib.pyplot as pit
# X-axis for time complexity
X::: [0,1,2,3,4,5,6,7,8,9,10]
# Y-axis values for time complexity
Y::: [0,1,4,9,16,25,36,49,64,81,100]
# Plot the graph

4
plt.plot(X,Y)
# Set the x-axis label
plt.xlabel('Input Size
(n)') # Set the y-axis
label
plt.ylabel('Time Complexity (n"2)')
# Title of the graph
plt.title('Time complexity graph of Binary search')
# Show the plot
plt.show()

Output:

' : Figure 1 D X

Time complexity graph of Binary search


100

80

60

40

I 20

5
c. Given a text txt [O...n-1] and a pattern pat [O...m-1], write a function
search (char pat [],char txt[]) that prints all occurrences of pat [] in txt [ ]. You may
assume that n > m.

Aim:
Write a Python program for pattern matching.
Algorithm:
1. Given a target string text and a pattern string pattern, initialize two pointers, i and j, to
traverse both strings.
2. Compare the characters of the target string and pattern string at the current positions
of i and j.
a. If the characters match, move both pointers to the next
b. If the characters do not match, reset j to the starting pq 1tion of the
pattern string and move i to the next position in the target tring.
3. Repeat steps 2 until either j has reached the end o:Nhetpattern string (indicating a
match) or i has reached the end of the target (indicating no match).
4. If j has reached the end of the pattern string, turn the index in the target string

where the match starts. If i has reached the ncl of the target string, return -1 to
indicate that the pattern is not present in the arg t string.

Program:
def search(pat, txt):
M ::: len(pat)

for i in r
j ::: 0
for j in range(M):
if txt[i + j] !:::patUJ:
break
if j :::::: M - 1:
print("Pattern found at index ", i)
txt:::"AABAACAADAABAAABAA"
pat:::"AABA"
search(pat, txt)

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

7
d. 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.

i) Insertion Sort:

Aim:
Write a Python program to sort the element using insertion sort method and
plot a graph of the time taken versus n.

Algorithm:
1. Given an array of elements, start with the second element.
2. For each element in the array, compare it with the ele to its left, swapping
it with the element to its left until it is in its correct o i• on in the sorted portion
of the array.
3. Repeat steps 2 for all elements in the arr .

The algorithm to plot a graph of the time taken versus n for insertion sort is
as follows:
1. Initialize an array time_tak to store the time taken to perform insertion sort for
different values of n.
2. For i in the ran e o n, do the following:
a. Ge e ate a list of i elements.
b. R cord the start time start_time just before performing insertion sort on the
st.
c. Perform insertion sort on the list.
d. Record the end time end_time just after performing insertion sort on
the list.
e. Calculate the time taken as time_taken[i] ::: end_tirne - start_tirne.
3. Plot a graph with non the x-axis and tirne_taken on the y-axis. This will give you
the graph of the time taken versus n for insertion sort.

8
Program:
# Function to do insertion sort
def insertionSort(arr):
# Traverse through 1 to len(arr)
for i in range(l, len(arr)):
key ::: arr[i]
# Move elements of arr[0..i-1], that are
# greater than key, to one position
ahead # of their current position
j ::: i-1
while j >:::0 and key < arr[j] :
arr[j+1] ::: arr[j]
j -:::1
arr[j+1] ::: key
# Driver code to test above
arr ::: []
n ::: int(input("Enter number of elements: ")
for i in range(0, n):
element ::: int(input("Enter element: )
arr.append(element)
insertionSort(arr)
print ("Sorted array is:")
for i in range(len(ar ) :
print ("%d" %arr[i])
import mat otlib.pyplot as pit
X::: [2, 3, 4, 5, 6, 7, 8, 9, 10]
y ::: [0, 0, 0.1, 0.3, 0.5, 0.7, 1.0, 1.3, 1.5]
plt.plot(x, y)
plt.xlabel('Size of array')
plt.ylabel('Complexity')
plt.title('Time Complexity of Insertion Sort')
pit.show()

9
Output:

Time Complexity of Insertion Sort

2 4 6

ii) Heap Sort:


Aim:

Write a Python program to sort the element s1:ng heap sort method and plot a
graph of the time taken versus n.

Algorithm:

1.
2. Swap the root (maximum val of the heap with the last element of the heap.
3. Discard the last element the heap, which is now in its correct position in the
sorted array.
4. Rebuild the max-heap, excluding the last element.
5. Repeat ste 2 to 4 until all elements are in their correct positions in the
sorted arra .
The algorithm to plot a graph of the time taken versus n for heap sort is as
follows:
1. Initialize an array time_taken to store the time taken to perform heap sort for
different values of n.
2. For i in the range 1 to n, do the following:
a. Generate a list of i elements.
b. Record the start time start_time just before performing heap sort on the list.
c. Perform heap sort on the list.
d. Record the end time end_time just after performing heap sort on the list.
e. Calculate the time taken as time_taken[i] ::: end_time - start_time.
10
3. Plot a graph with non the x-axis and time_taken on the y-axis. This will give you
the graph of the time taken versus n for heap sort.

Program:
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::: [ 12, 11, 13, 5, 6, 7]
heapSort(arr)
n ::: len(arr)
print ("Sorted array is")
for i in range(n):
print ("%d" %arr[i])
import timeit
import matplotlib.pyplot as pit
# list of integers to be sorted
list_length:::[10000,20000,30000 4 000,50000,60000]
# empty list to store times take reach list
time_taken:::[]
# looping through the Ii .t
for i in range(le • t_length)):
# code snippet to be executed only once
setup_code :::
111

from heapq import heappush, heappop


from random import randint'"
# code snippet whose execution time is to be measured
test_code :::
111

I ::: []

11
Output:

, Figure 1 D X

HeapSort

0.03

0.02

0.01

10000 20000 30000 40000 50000 60000

12
2. GRAPH ALGORITHMS:
a. Develop a program to implement graph traversal using Breadth
First Search from collections import defaultdict
Aim:
Write a Python program to perlorm graph traversal using Breadth First Search
Algorithm:
1. Create an empty queue and push the starting node onto it.
2. Repeat the following steps until the queue is empty:
a. Dequeue a node from the queue and mark it as visited.
b. For each unvisited neighbor of the current node, mark it as visited and
enqueue it.
3. Once the queue is empty, the algorithm is complete.
Program:

class Graph:
c,O
def _init_(self):
self.graph ::: defaultdict(list)
def addEdge(self, u, v):
self.graph[u].append( v)
def BFS(self, start):
0
visited ::: [False] * Jen
queue:::[]
queue.append uht)
visited[ t ::: True
while ue:
start ::: queue.pop(0)
print(start, end:::" ")
for i in self.graph[start]:
if not visited[i]:
queue.append(i)
visited[i] ::: True
if name_ :::::: '_main_':
g ::: Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)

13
g.addEdge(l, 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

14
b. Develop a program to implement graph traversal using Depth
First Search
Program:
Aim:
Write a Python program to perlorm graph traversal using depth First Search

Algorithm:
1. Create a stack and push the starting node onto it.

2. Repeat the following steps until the stack is empty:

a. Pop a node from the stack and mark it as visited.

b. For each unvisited neighbor of the current node, ar it as visited and


push it onto the stack.

3. Once the stack is empty, the algorithm is compl te.

Program:
# define a graph
graph::: {
'A' : ['B','C'],
'B': ['D', 'E1,
'C': ['F'],
'D': [],
'E':
['F'], 'F':
[]

visite ::: set() # Set to keep track of visited nodes.


print("The DPS Traversal : Node visited order is")
def dfs(visited, graph, node):
if node not in visited: # if the node is not visited then visit it and add it to the
visited set.
print (node) # print the node.
visited.add(node) # add the node to the visited set.
for neighbour in graph[node]: # for each neighbour of the current node do a
recursive call.
dfs(visited, graph, neighbour)# recursive call.
15
Output:
The DFS Traversal : Node visited order is
A

B
D
E
F
C

16
c. From a given vertex in a weighted connected graph, develop a
program to find the shortest pathsto other vertices using Dijkstra's
algorithm.

Aim:
Write a Python program to find the shorte t paths to other vertices using
Dijkstra's algorithm in a weifgted graph.

Algorithm:
1. Create a set S to keep track of visited vertices, and initialize it with the
starting vertex.
2. Create a priority queue Q to keep track of unvisited vertice d their
distances, and initialize it with the starting vertex and a • tance of 0.
3. Repeat the following steps until Q is empty:
1. Dequeue the vertex u with the minimu distance from Q.
11. Add u to S.
m. For each neighbor v of u:
1v. If vis already in S, contin
v. If the distance to v throu h u is less than its current distance, update its
distance in .
4. Once Q is empty, th :-distances to all vertices have been determined.
Program:
# define the graph
graph::: {
'A': { 'B': 5, 'C': 1},
'B': {A: 5, 'C': 2, 'D': 1},
'C': {'A': 1, 'B': 2, 'D': 4, 'E': 8},
'D': { 'B': 1, 'C': 4, 'E': 3, 'F': 6},
'E': { 'C': 8, 'D': 3},
'F': {'D': 6}
}
def dijkstra(graph,start,goal):
shortest_distance ::: {}
predecessor ::: { }
unseenNodes ::: graph
17
infinity ::: 99999
path::: []
for node in unseenNodes:
shortest_distance[node] ::: infmity
shortest_distance[start] ::: 0
while unseenNodes:
minNode ::: None
for node in unseenNodes:
if minNode is None:
minNode::: node
elif shortest_distance[node] < shortest_distance[minNod }:
minNode::: node
for childNode, weight in graph[minNode].itemsO:
if weight+ shortest_distance[minNode] <
shortest_distance[childNode]:
shortest_distance[childNode] ::: w ht+ shortest_distance[minNode]
predecessor[childNode] ::: rn.in'No e
unseenNodes.pop(minNode)
currentNode ::: goal
while currentNode !::: start:
try:
path.insert(t) chrrentNode)
curreo ode::: predecessor[currentNode]

break
path.insert(0,start)
if shortest_distance[goal] !::: infinity:
print('Shortest distance is '+ str(shortest_distance[goal]))
print('And the path is '+ str(path))
dijkstra(graph, 'A', 'F')
Output:
Shortest distance is 10
And the path·l s ['A, ' 'C'' ' B, ' 'D'' 'F']

18
d. Find the minimum cost spanning tree of a given undirected graph using
Prim's algorithm.

Aim:
Write a Python program to Find the minimum cost spanning tree of a given
undirected graph using Prim's algorithm.

Algorithm:
1. Create a set V to keep track of visited vertices, and initialize it with an
arbitrary starting vertex.
2. Create a priority queue Q to keep track of unvisited vertice d their distances
to V, and initialize it with all vertices adjacent to the st i!}g vertex.
3. Repeat the following steps until V contains all verti e
1. Dequeue the vertex u with the minimu di tance from Q.
11. Add u to V.
m. For each unvisited neighbor v u:
1v. If vis already in V, con• e.
v. If the distance to v throu h u is less than its current distance in Q,
update its d t in Q.
4. Once V contains all v ices, the minimum cost spanning tree has been
constructed.
Program:
v5
graph [0 , 0, 6, O],
[2, 0, 3, 8, 5],
[0, 3, 0, 0, 7],
[6, 8, 0, 0, 9],
[0, 5, 7, 9, 0]]
def rninKey(key, rnstSet):
# Initialize min value
min float('inf)
for v in range(V):
if key[v] < min and rnstSet[v]. False:
min key[v]

19
rnin_index ::: v
return rnin_index
def primMST(graph):
key::: [tloat('inf)] * V
parent:::[None] * V
key[O] ::: 0
mstSet ::: [False] * V
parent[O] ::: -1
for cout in range(V):
u ::: minKey(key, mstSet)
mstSet[u] ::: True
for v in range(V):
if graph[u][v] > 0 and mstSet[v] :::::: False and key[v.J graph[u][v]:
key[v] ::: graph[ u][ v]
parent[v] :::
u print("Edge \tWeight")
for i in range(l,V):
11 11 11
print(parent[i], - , i,"\t ,graph[j,] arent[i] ])
g ::: primMST(graph)

Output:

Edge ight
0-1 >--i
1-2 3
0-3 6
1-4 5

20
e. Implement Floyd's algorithm for the All-Pairs- Shortest-Paths problem.

Aim:
Write a Python program to find all pairs - Shortest paths problem using
Floyd's algorithm
Algorithm:
1. Create a table of distances between every pair of vertices in G
2. Initialize the shortest path table to be the same as the distance table
3. Fork:::Otok-1
1. For each pair of vertices (u, v) in G
u. For each vertex w in the set of vertices V
iji_ Set the shortest path between u and v to the mini m of the current
shortest path and the sum of the shorte t aths between u and w and
wand v.
4. Return the shortest path table.
Program:
graph ::: [[0, 5, 9, 7],
(4, 0, 2, 8],
(3, 2, 0, 1],
(6, 5, 2, OJ]
n ::: len(graph)
dist::: [[float('inf) od in range(n)] for j in range(n)]
for i in range n :
for j•

fork in range(n):
for i in range(n):
for j in range(n):
dist[i]UJ ::: mm(dist[i][j], dist[i][k] + dist[k][j])
print(dist)

Output:
[[0, 5, 7, 7], [4, 0, 2, 3], [3, 2, 0, 1], [5, 4, 2, OJ]

21
f. Compute the transitive closure of a given directed graph using
Warshall's algorithm.

Aim:
Write a Python program to compute the transitive closure of a directed graph
using Warshall's algorithm
Algorithm:
1. Create an adjacency matrix of the graph.
2. Initialize the matrix with the values of the graph.
3. For each vertex v, set the value of the matrix at row v and column v to 1.
4. For each pair of vertices (u, v), if there is an edge from u to v set the value of
the matrix at row u and column v to 1.
5. For each triplet of vertices (u, v, w), if the value o matrix at row u and
column v is 1 and the value of the matrix at ro v and column w is 1, set the
value of the matrix at row u and column w to 1.
6. Repeat step 5 until no more changes can.be made. The matrix now contains
the transitive closure of the graph.

Program:
#Define the graph
graph::: {
'A': ['B', 'C'],
'B': ['C', 'Dl

#Define a function to compute the transitive closure


def transitive_closure(graph):
#Initialize the transitive closure matrix with Os
closure_matrix::: [[0 for j in range(len(graph))] for i in range(len(graph))]
#Fill the closure matrix with 1s for direct paths
for i in range(len(graph)):
for j in graph[list(graph.keys())[i]]: closure_matrix[i]
[list(graph. keys()). index(j)] ::: 1

22
#Compute the transitive closure using WarshaJl's
algorithm fork in range(len(graph)):
for i in range(len(graph)):
for j in range(len(graph)):
closure_matrix[i][j]:::closure_matrix[i][j] or (closure_matrix[i][k] and
closure_matrix[k][j])
#Print the transitive closure matrix
for row in closure_matrix:
print(row)
#Call the function
transitive_closure(graph)

Output:
[0, 1, 1, 1]
[0, 0, 1, 1]
[0, 0, 1, 1]
[0, 0, 1, 1]

23
3. ALGORITHM DESIGN TECHNIQUES:
a. Develop a program to find out the maximum and minimum numbers in a
given list of n numbersusing the divide and conquer technique.

Aim:
Write a Python program to find out the maximum and minimum numbers
in a given list of n numbersusing the divide and conquer technique.

Algorithm:
1. Divide the list into two halves.
2. Find the maximum and minimum numbers in each half.
3. Compare the two maximum numbers and select the ma i um of the two.
4. Compare the two minimum numbers and select th minimum of the two.
5. The maximum and minimum numbers of the li are the maximum and
minimum of the two numbers selected in st p and 4.
Program:
def fmd_max_min( numbers):
if len(numbers) :::::: 1:
return (numbers[O], num rs[O])
mid:::len(numbers) 2
left_max, left_ • ::: find_max_min(numbers[:rnid])
right_max nght_min:::fmd_max_min(numbers[mid:])
return ,max(left_max, right_max), min(left_min, right_min))
# dr·:v code
n m'bers:::[3, 5, 2, 8, 1, 4, 10]
max_num, rnin_num:::find_max_min(numbers)
print("Maximum number is:", max_num)
print("Minimum number is:", min_num)
Output:
Maximum number is: 10
Minimum number is: 1

24
b. 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 inthe list to be sorted and plot a graph of
the time taken versus n.

b.i ) Merge sort:

Aim:
Write a Python program to sort the elements using merge sort and plot a graph
to the time taken versus n

Algorithm:
Merge Sort is a divide and conquer algorithm. It divld input array in two
halves, calls itself for the two halves and then merges t e two sorted halves.
1. Divide the unsorted array into n partitions, each ition contains 1 element.
2. Repeatedly merge partitioned units to proda new sublists until there is only 1
sublist remaining. This will be the sorted lis .
3. Compare the first element of the sub1i t with the first element of the sublist to its
right.
4. Merge the two sublists by omparing each element of the sublist and placing the
smaller element into th w sublist.
5. Repeat step 3 and until all sublists are merged into a single sorted sublist.

Program·
1mpo ime
import matplotlib
def merge_sort(arr):
if len(arr) >1:
mid ::: len(arr)//2
L:::arr[:mid]
R ::: arr[mid:]
merge_sort(L)
merge_sort(R)
i:::j:::k:::O

25
while i < len(L) and j < len(R):
if L[i] < R[j]:
arr[k] ::: L[i]

else:
arr[k] :::
R[j] j+:::l
k+:::l
while i < len(L):
arr[k] ::: L[i]

k+:::l
while j < len(R):
arr[k] ::: R[j]
j+:::l
k+:::l
n::: [1000, 2000, 4000, 8000]
time_taken ::: []
for i inn:
arr::: [i for i in range(i)]
start_time ::: time.tun J
merge_sort(arr)
end_time:::, one.time()
time n.append(end_time -
start_time) 1mpo atplotlib.pyplot as pit
plt.plot(n, time_taken)
plt.xlabel('Number of elements in the list')
plt.ylabel('Time taken to sort')
plt.title('Merge Sort')
pit.show()

Output:

26
Merge Sort

1000 2000 3000 4000 5000 6000 7000 8000

27
b.ii) Quick Sort:
Aim:
Write a Python program to sort the elements using quick sort and plot a graph
to the time taken versus n

Algorithm:
1. Select a pivot element from the array.
2. Partition the array into two sub-arrays. The elements in the first sub-array are
less than the pivot element, while the elements in the second sub-array are
greater than the pivot element.
3. Recursively sort the sub-arrays created in Step 2.
4. Join the sub-arrays and the pivot element together to obt n the sorted array.

Program: c,O
import time
import matplotlib.pyplot as
pit def quick_sort(arr):
if len(arr) <::: 1:
return arr
pivot ::: arr[len(arr) // 2]
left::: [x for x in ar • iis. < pivot]

arr if x = pivot]
right ::: [ x o
return u·d:_sort(left) +middle+ quick_sort(right)
# Gen ate an array of random numbers
arr::: [5, 6, 7, 8, 1, 2, 12, 14]
# Calculate the time taken to sort the array
start::: time.time()
sorted_arr ::: quick_sort(arr)
end ::: time.time()
# Print the sorted array
print("Sorted array:", sorted_arr)
# Calculate and print the time taken to sort the array
print("Time taken:", end - start, "seconds")

28
# Plot a graph of the time taken versus n
n_values ::: [10, 100, 1000, 10000]
time_values ::: []
for n in n_values:
arr ::: [i for i in range(n)]
start ::: time.time()
sorted_arr ::: quick_sort(arr)
end ::: time.time()
time_values.append(end -
start) plt.plot(n_values,
time_values)
plt.xlabel("n")
plt.ylabel("Time taken")
plt.title("Qu icksort")
pit.show()

Output:

Quicksort

0 2000 4000 6000 8000 10000

29
4. STATE SPACE SEARCH ALGORITHMS:
a. Implement N Queens problem using Backtracking.
Aim:
Write a Python program to solve N- Queens problem using backtracking.
Algorithm:
II Create an empty array of size n

II Create a function to check if a queen can be placed in a given row and


column

II Create a function to place a queen in a given row and column

II Create a function to remove a queen from a given row and column

II Create a function to solve the n queens problem using ba racking

II Function to check if a queen can be placed in a gi n row and

column func canPlaceQueen(row, col int, board □[]int beol {

II Check if any other queen is placed n the same row

for i :::: O; i < len(board); iyt

if board[row][i] -- 1 {

ret false

II Check if other queen is placed in the same column

for i :c: O· 1 < len(board); i++ {

if board[i][col] :::::: 1 {

return false } }

II Check if any other queen is placed in the diagonal

for i, j ::::row, col; i >::: 0 &&j >::: O; i, j:::i-1, j-1 {

if board[i][j] :::::: 1 {

return false

for i, j :::: row, col; i < len(board) && j >::: O; i, j ::: i+1, j-1 {

if board[i][j] :::::: 1 {

return false

return true }

30
II Function to place a queen in a given row and column
func placeQueen(row, col int, board[][] int) {

board[row][col]:::1}

II Function to remove a queen from a given row and column


func removeQueen(row, col int, board[][] int) {

board[row][col]:::0 }

II Function to solve then queens problem using backtracking


func solveNQueens(board[][] int) boot {

if len(board) :::::: 0 {

return true }

for i :::: O; i < len(board); i++ {

for j :::: O; j < len(board); j L


if canPlaceQue j, board)

{ pla ueen( j, board)

solveNQueens(board) {

return true }

removeQueen(i, j, board)

return false }

Program:
# N-Queens problem using Backtracking
# global variable for board
board:::[]
# function to print the board
def print_board(board):
for i in range(len(board)):
for j in range(len(board[O])):
print(board[i][j], end ::: " ")
print()

31
# function to check if a queen can be placed in a position
def is_safe(board, row, col):
# check row
for i in range(col):
if board[row ][i] :::::: 1:
return False
# check upper diagonal
for i, j in zip(range(row, -1, -1), range(col, -1, -1)):
if board[i][j] :::::: 1:
return False
# check lower diagonal
for i, j in zip(range(row, len(board)), range(col, -1, -1)):
if board[i][j] :::::: 1:
return False
return True
# function to solve the N-Queens
problem def solve_n_queens(board, col):
# base case
if col>::: len(board):
return True
# iterate through all mw
for i in range(len board)):
if is_safe(board, i, col):
#pJ ce ueen
ard[i][col] ::: 1
# recur to place rest of the queens
if solve_n_queens(board, col + 1) :::::: True:
return True
# backtrack board[i]
[col] ::: 0
return False
# driver code
if name_ main
11 11

# size of board

32
n:::int(input("Enter the size of board: "))
# create an empty board
board:::[[0 for j in range(n)] for i in range(n)]
if solve_n_queens(board, 0) :::::: False:
print("Solution does not
exist") else:
print_board(board)
Output:
Enter the size of board: 4
0010
1000
0001
0100

33
5. APPROX™ATION ALGORITHMS RANDOMIZED ALGORITHMS:

a. hnplement 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

Aim:
Write a Python program to find the optimal solution for the Travelling
Salesperson problem using approximation algorithm and determine the error in
the approximation

Algorithm:
1. Initialize the solution with the first city as the starting point.
2. Calculate the distance from the current city to aU her cities.
3. Select the nearest city from the current cit: mark it as visited.
4. Calculate the total distance travelled far.
5. Repeat steps 2-4 until all cities hav een visited.
6. Calculate the total distance trav lled.
7. Compare the total dista travelled with the optimal solution.
8. If the total distance tra e ed is less than the optimal solution, then the current
solution is the a proximate solution.
9. If the total dt ance travelled is more than the optimal solution, then repeat steps
2- 7 using-a ifferent starting city.

Program:
#importing libraries
import numpy as np
import math
#defming the distance matrix
dist_rnatrix:::np.array([[O, 10, 15, 20],
[10, 0, 35, 25],
[15, 35, 0, 30],
[20, 25, 20, 0]])

34
#defming the cost matrix
cost_matrix:::np.array([[O, 10, 15, 20],
[10, 0, 35, 25],
[15, 35, 0, 30],
[20, 25, 20, 0]])
#defming the number of cities
num_cities ::: 4
#defining the optimal solution function
def opt_solution(dist_matrix, cost_matrix, num_cities):
#initializing the cost matrix
cost_matrix:::np.zeros((num_cities, num_cities))
#initializing the visited array
visited ::: [False] * num_cities
#initializing the current city
current_city:::0
#initializing the total cost
total_cost ::: 0
#updating the visited array
visited[current_city] ::: Tru
0
#looping through the cit"
for i in range(num 1• s - 1):
#initializin th .min_cost
min_co t - math.inf
#initia "zing the next_city
n t_city ::: 0
#looping through the
cities for j in
range(num_cities):
#checking if the city has been visited
if visited[j] :::::: False:
#checking if the cost is less than min_cost
if cost_matrix[current_city][j] < min_cost:
#updating the rnin_cost
min_cost ::: cost_matrix[current_city][j]
#updating the next_city
35
next_city ::: j
#updating the total cost
total_cost +::: min_cost
#updating the visited array
visited[next_city] ::: True
#updating the current city
current_city ::: next_city
#returning the total cost
return total_cost

#calculating the optimal solution


opt_sol:::opt_solution(dist_matrix, cost_matrix, num_cities)
#printing the optimal solution

print("Optimal Solution: ", opt_sol) c,O


#defining the approximation algorithm 0
def approx_algorithm(dist_matrix, cost_matt1x um_cities):
#initializing the cost matrix
cost_matrix:::np.zeros((num_citi num_cities))
#initializing the visited arr r
visited::: [False] * num_cities
#initializing the curr nt city
current_city:::0
#initializin e total cost
total co ::: 0
visit urrent_city] ::: True
for i in range(num_cities -
1):
#initializing the min_cost
min_cost:::math.inf
#initializing the next_city
next_city ::: 0
#looping through the cities
for j in range(num_cities):
if visited[j] :::::: False:
if dist_matrix[current_city][j] < min_cost:

36
#updating the min_cost
min_cost ::: dist_matrix[current_city][j]
#updating the next_city
next_city ::: j
total_cost +::: min cost
#updating the visited array
visited[next_city] ::: True
#updating the current city
current_city ::: next_city
#returning the total cost
return total_cost
approx_sol:::approx_algorithm(dist_matrix, cost_matrix, num_cities)
#printing the approximated solution

print("Approximated Solution: ",


c,O
approx_sol) #calculating the error
error ::: opt_sol - approx_sol
#printing the error
print("Error: ", error)

Output:

37
b Implement randomized algorithms for finding the kth smallest
number. Aim:
Write a Python program to find the kth smallest number using randomized
algorithm
Algorithm:
1. Create an array of size n, where n is the number of elements in the array.

2. Randomly select an element from the array and store it in a variable.

3. Compare the randomly selected element with the kth smallest element.

4. If the randomly selected element is smaller than the kth smallest element, then
replace the kth smallest element with the randomly selected lement.

5. Repeat steps 2-4 until the kth smallest element is found.

Program:
import random
def kthSmallest(arr, k):
n ::: len(arr)
temp ::: arr[:k]
random.shuffle(temp)
for i in range n :
fo • ·n range(k):
if arr[i] < temp[j]:
temp[j] :::
arr[i] break
return temp[k - 1]
# Driver Code
arr::: [12, 3, 5, 7, 19]
k::: 2
print("K'th smallest element is", kthSmallest(arr, k))

Output:
K'th smallest element is 5

38

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy