Cs3401 Lab Manual
Cs3401 Lab Manual
2001
0V
LAB MANUAL
for
CS3401-ALGORifflMS LABORATORY
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
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
).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
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
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:
2 4 6
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
I ::: []
11
Output:
, Figure 1 D X
HeapSort
0.03
0.02
0.01
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.
Program:
# define a graph
graph::: {
'A' : ['B','C'],
'B': ['D', 'E1,
'C': ['F'],
'D': [],
'E':
['F'], 'F':
[]
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
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.
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
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
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
if board[row][i] -- 1 {
ret false
if board[i][col] :::::: 1 {
return false } }
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}
board[row][col]:::0 }
if len(board) :::::: 0 {
return true }
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
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
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.
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.
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