0% found this document useful (0 votes)
43 views19 pages

Daa Lab Manual

The document is a lab manual for the Design and Analysis of Algorithms course at Visvesvaraya Technological University, detailing various sorting algorithms (Selection Sort, Quick Sort, Merge Sort) and their time complexity analysis using Python. It includes code examples for each algorithm, instructions for generating random input, and methods for plotting the time complexity graphs. Additionally, it covers solving the All-Pairs Shortest Paths problem using Floyd's algorithm and the Traveling Salesman Problem using Dynamic Programming.

Uploaded by

najeebahmed5007
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
43 views19 pages

Daa Lab Manual

The document is a lab manual for the Design and Analysis of Algorithms course at Visvesvaraya Technological University, detailing various sorting algorithms (Selection Sort, Quick Sort, Merge Sort) and their time complexity analysis using Python. It includes code examples for each algorithm, instructions for generating random input, and methods for plotting the time complexity graphs. Additionally, it covers solving the All-Pairs Shortest Paths problem using Floyd's algorithm and the Traveling Salesman Problem using Dynamic Programming.

Uploaded by

najeebahmed5007
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

VISVESWARAYA TECHNOLOGICAL UNIVERSITY,BELGAUM

CENTRE FOR PG STUDIES /REGIONAL OFFICE KUSNOOR ROAD,KALBURAGI

LAB MANUAL
DESIGN AND ANALYSIS OF ALGORITHEMS(BUE401)

B.TECH SEM-IV ECE(2023-24)

DEPARTMENT OF ELECTRONICS AND COMPUTER & ENGINEERING


DESIGN AND ANALYSIS OF ALGORITHEMS(BUE401)

Prof.Ambika Shahbadkar
(Assistance Professor)
Department of computer science and engineering
DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

1. Sort a given set of n integer elements using Selection Sort method and compute its time
complexity. Run the program for varied values of n> 5000 and record the time taken to sort. Plot a
graph of the time taken versus n. The elements can be read from a file or can be generated using the
random number generator. Demonstrate using C/C++/Python how the brute force method works
along with its time complexity analysis: worst case, average case and best case.

import time
import random
import matplotlib.pyplot as plt
arr = input("Enter the list of elements separated by space: ").split()
arr = [int(x) for x in arr]
print("Input array: ", arr)
n = len(arr)
def selection_sort(arr):
for i in range(n):
min_idx = i
for j in range(i+1, n):
if arr[j]<arr[min_idx]:
min_idx = j
arr[i], arr[min_idx] = arr[min_idx], arr[i]
return arr
sorted_arr = selection_sort(arr)
print("Sorted array", sorted_arr)
# time taken to sort
start_time = time.time()
sorted_arr = selection_sort(arr)
end_time = time.time()
print("Time taken to sort", end_time - start_time, "seconds")
# For n>5000
n_values = [5000, 6000, 7000, 8000]
time_values = []
for n in n_values:
arr = [random.randint(1, 9) for _ in range(n)] # Generating random
start_time = time.time()
sorted_arr = selection_sort(arr)
end_time = time.time()
time_taken = end_time - start_time
print("Time taken to sort",n, "Elements:",time_taken, "seconds")
time_values.append(time_taken)

# plotting the graph


plt.plot(n_values, time_values)
plt.xlabel('Number of Elements (n)')
plt.ylabel('Time taken in seconds')
plt.title('Time Compexity Analysis of Selection sort')
plt.grid(True)
plt.show()

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 1


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

output
Enter the list of elements separated by space: 12 11 13 5 6 7
Input array: [12, 11, 13, 5, 6, 7]
Sorted array [5, 6, 7, 11, 12, 13]
Time taken to sort 0.0 seconds
Time taken to sort 5000 Elements: 0.2671678066253662 seconds
Time taken to sort 6000 Elements: 0.3778214454650879 seconds
Time taken to sort 7000 Elements: 0.5204188823699951 seconds
Time taken to sort 8000 Elements: 0.676368236541748 seconds

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 2


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

2. Sort a given set of n integer elements using Quick Sort method and compute its time
complexity. Run the program for varied values of n> 5000 and record the time taken to sort. Plot a
graph of the time taken versus n. The elements can be read from a file or can be generated using
the random number generator. Demonstrate using C/C++/Python how the divide-and-conquer
method works along with its time complexity analysis: worst case, average case, and best case.

import time
import random
import matplotlib.pyplot as plt
arr = input("enter the list of elements seperated by space: ").split()
arr = [int(x) for x in arr]
print("input array: ",arr)
def quick_sort(arr):
if len(arr)<=1:
return arr
# choose a last element as pivot
pivot = arr[len(arr)-1]
#initialize left and right array
left = []
right = []
# partitioning the array into left and right subarray
for i in range(len(arr)-1):
if arr[i]<pivot:
left.append(arr[i])
else:
right.append(arr[i])
return quick_sort(left)+[pivot]+quick_sort(right)
sorted_arr = quick_sort(arr)
print("sorted array: ",sorted_arr)
# measure time taken to sort
start_time = time.time()
sorted_arr = quick_sort(arr)
end_time = time.time()
print("time taken to sort : ",end_time - start_time, "seconds")
# for n>5000
n_values = [5000,6000,7000,8000]
time_values = []
for n in n_values:
arr = [random.randint(1,9) for _ in range(n)] # generate random array
start_time = time.time()
sorted_arr = quick_sort(arr)
end_time = time.time()
time_taken = end_time - start_time
print("time taken to sort", n, "elements:", end_time-start_time, "seconds")
time_values.append(time_taken)

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 3


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

#plotting the graph


plt.plot(n_values,time_values)
plt.xlabel("number of elements ")
plt.ylabel("time taken in seconds")
plt.title(" time complexity analysis of quick sort")
plt.grid(True)
plt.show()

output
enter the list of elements seperated by space: 12 11 13 5 6 7
input array: [12, 11, 13, 5, 6, 7]
sorted array: [5, 6, 7, 11, 12, 13]
time taken to sort : 0.0 seconds
time taken to sort 5000 elements: 0.0527496337890625 seconds
time taken to sort 6000 elements: 0.09432673454284668 seconds
time taken to sort 7000 elements: 0.11038565635681152 seconds
time taken to sort 8000 elements: 0.14146757125854492 seconds

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 4


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

3. Sort a given set of n integer elements using Merge Sort method and compute its time complexity.
Run the program for varied values of n> 5000, and record the time taken to sort. Plot a graph of the
time taken versus n. The elements can be read from a file or can be generated using the random
number generator. Demonstrate using C/C++/Python how the divide-and-conquer method works
along with its time complexity analysis: worst case, average case, and best case.
import time
import random
import matplotlib.pyplot as plt
arr = input("enter the list of elements seperated by space: ").split()
arr = [int(x) for x in arr]
print("input array: ",arr)
def merge_sort(arr):
if len(arr)<=1:
return arr
mid = len(arr)//2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left,right)
def merge(left,right):
result = []
i=j=0

while i< len(left) and j < len(right):


if left[i] < right[j]:
result.append(left[i])
i = i+1
else:
result.append(right[j])
j = j+1
result.extend(left[i:])
result.extend(right[j:])
return result
sorted_arr = merge_sort(arr)
print("sorted array: ",sorted_arr)
# measure time taken to sort
start_time = time.time()
sorted_arr = merge_sort(arr)
end_time = time.time()
print("time taken to sort : ",end_time - start_time, "seconds")

# for n>5000
n_values = [5000,6000,7000,8000]
time_values = []
for n in n_values:
arr = [random.randint(1,9) for _ in range(n)] # generate random array
start_time = time.time()
sorted_arr = merge_sort(arr)

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 5


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

end_time = time.time()
time_taken = end_time - start_time
print("time taken to sort", n, "elements:", end_time-start_time, "seconds")
time_values.append(time_taken)
#plotting the graph
plt.plot(n_values,time_values,'purple')
plt.xlabel("number of elements ")
plt.ylabel("time taken in seconds")
plt.title(" time complexity analysis of merge sort")
plt.grid(True)
plt.show()

output
enter the list of elements seperated by space: 12 11 13 5 6 7
input array: [12, 11, 13, 5, 6, 7]
sorted array: [5, 6, 7, 11, 12, 13]
time taken to sort : 0.0 seconds
time taken to sort 5000 elements: 0.0 seconds
time taken to sort 6000 elements: 0.0 seconds
time taken to sort 7000 elements: 0.010013818740844727 seconds
time taken to sort 8000 elements: 0.0 seconds

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 6


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

4. Write C/C++/Python programs to

1. Solve All-Pairs Shortest Paths problem using Floyd's algorithm.

n = 4 #Number of vertices
inf = float('inf')
graph = [[0,3,inf,7],
[8,0,2,inf],
[5,inf,0,1],
[2,inf,inf,0]]
def floyd_warshall(graph):
n = len(graph)
dist = []
for row in graph:
dist.append(row[:])
for k in range(n):
for j in range(n):
for i in range(n):
dist[i][j] = min(dist[i][j],dist[i][k]+dist[k][j])
return dist
shortest_paths = floyd_warshall(graph)
# printing Output:
print("shortest_paths between all pairs of vertices:")
for row in shortest_paths:
for dist in row:
if dist == inf:
print("inf",end = " ")
else:
print(dist,end = " ")
print()

output
shortest_paths between all pairs of vertices:
0356
5023
3601
2570
Or

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 7


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

# Input
n = int(input("Enter the number of vertices:"))
inf = float('inf')
print("enter the adjacency matrix separated by space")
# enter inf for infinity
graph = []
for i in range(n):
row = input().split()
graph.append([inf if x == 'inf' else int(x) for x in row])
def floyd_warshall(graph):
n = len(graph)
dist = []
for row in graph:
dist.append(row[:])
for k in range(n):
for j in range(n):
for i in range(n):
dist[i][j] = min(dist[i][j],dist[i][k]+dist[k][j])
return dist
shortest_paths = floyd_warshall(graph)
# printing Output:
print("shortest_paths between all pairs of vertices:")
for row in shortest_paths:
for dist in row:
if dist == inf:
print("inf",end = " ")
else:
print(dist,end = " ")
print()

output
Enter the number of vertices:4
enter the adjacency matrix separated by space
0 3 inf 7
8 0 2 inf
5 inf 0 1
2 inf inf 0
shortest_paths between all pairs of vertices:
0356
5023
3601
2570

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 8


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

2.Solve Traveling salesperson problem using Dynamic Programming


class TravellingSalesmanProblem:
def __init__(self, distance, start):
self.distance_matrix = distance
self.start_city = start
self.total_cities = len(distance)
self.end_state = (1 << self.total_cities) - 1
self.memo = [[None for _col in range(1 << self.total_cities)] for _row in range(self.total_cities)]
self.shortest_path = []
self.min_path_cost = float('inf')
def solve(self):
self.__initialize_memo()
for num_element in range(3, self.total_cities + 1):
for subset in self.__initiate_combination(num_element):
if self.__is_not_in_subset(self.start_city, subset):
continue
for next_city in range(self.total_cities):
if next_city == self.start_city or self.__is_not_in_subset(next_city, subset):
continue
subset_without_next_city = subset ^ (1 << next_city)
min_distance = float('inf')
for last_city in range(self.total_cities):
if last_city == self.start_city or \
last_city == next_city or \
self.__is_not_in_subset(last_city, subset):
continue
new_distance = \
self.memo[last_city][subset_without_next_city] +
self.distance_matrix[last_city][next_city]
if new_distance < min_distance:
min_distance = new_distance

self.memo[next_city][subset] = min_distance
self.__calculate_min_cost()
self.__find_shortest_path()
def __calculate_min_cost(self):
for i in range(self.total_cities):
if i == self.start_city:
continue
path_cost = self.memo[i][self.end_state]
if path_cost < self.min_path_cost:
self.min_path_cost = path_cost

def __find_shortest_path(self):
state = self.end_state
for i in range(1, self.total_cities):

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 9


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

best_index = -1
best_distance = float('inf')
for j in range(self.total_cities):
if j == self.start_city or self.__is_not_in_subset(j, state):
continue
new_distance = self.memo[j][state]
if new_distance <= best_distance:
best_index = j
best_distance = new_distance
self.shortest_path.append(best_index)
state = state ^ (1 << best_index)
self.shortest_path.append(self.start_city)
self.shortest_path.reverse()
def __initialize_memo(self):
for destination_city in range(self.total_cities):
if destination_city == self.start_city:
continue

self.memo[destination_city][1 << self.start_city | 1 << destination_city] = \


self.distance_matrix[self.start_city][destination_city]
def __initiate_combination(self, num_element):
subset_list = []
self.__initialize_combination(0, 0, num_element, self.total_cities, subset_list)
return subset_list
def __initialize_combination(self, subset, at, num_element, total_cities, subset_list):
elements_left_to_pick = total_cities - at
if elements_left_to_pick < num_element:
return
if num_element == 0:
subset_list.append(subset)
else:
for i in range(at, total_cities):
subset |= 1 << i
self.__initialize_combination(subset, i + 1, num_element - 1, total_cities, subset_list)
subset &= ~(1 << i)
@staticmethod
def __is_not_in_subset(element, subset):
return ((1 << element) & subset) == 0
if __name__ == '__main__':

distance_matrix = [
[0, 328, 259, 180, 314, 294, 269, 391],
[328, 0, 83, 279, 107, 131, 208, 136],
[259, 83, 0, 257, 70, 86, 172, 152],
[180, 279, 257, 0, 190, 169, 157, 273],
[314, 107, 70, 190, 0, 25, 108, 182],
[294, 131, 86, 169, 25, 0, 84, 158],

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 10


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

[269, 208, 172, 157, 108, 84, 0, 140],


[391, 136, 152, 273, 182, 158, 140, 0],
]

start_city = 0
tour = TravellingSalesmanProblem(distance_matrix, start_city)
tour.solve()
print("Shortest path :", tour.shortest_path)
print("Minimum path cost :", tour.min_path_cost)

output
Shortest path : [0, 3, 6, 5, 4, 2, 1, 7]
Minimum path cost : 735

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 11


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

5.Design and implement c/c++/python program to find a subst of given set ={S1,s2,…..Sn} of n
positive integer whose SUM is equal to a given positive integer d.For example ,if as={1,,2,5,6,8} and
d= 9,there are two solutions {1,2,6} and {1,8} Display a suitable message if the given problem
instance doesn’t have a solution.

# INPUT
S = input("eneter the elements of set S seperated by space: ").split()
S = [int(x) for x in S]
print("set S : ",S)
# target sum
d = int(input("enter the sum d: "))
# print("target sum d :",d)
def sum_of_subset(S,d):
result = []
def backtrack(start, current_subset, current_sum):
if current_sum == d:
result.append(list(current_subset))
return
if current_sum > d:
return
for i in range(start, len(S)):
current_subset.append(S[i])
backtrack(i + 1, current_subset, current_sum + S[i])
current_subset.pop()
backtrack(0, [], 0)
return result
subsets = sum_of_subset(S,d)
if subsets:
print("subsets whose sum is ",d, "are:")
for j in subsets:
print(j)
else:
print("no subset found with sum: ",d)

output
eneter the elements of set S seperated by space: 1 2 5 6 8
set S : [1, 2, 5, 6, 8]
enter the sum d: 9
subsets whose sum is 9 are:
[1, 2, 6]
[1, 8]

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 12


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

6.Design and implement c/c++/python program to find all Hamiltonian cycle in a connected
undirected Graph G of n vertices using Backtracking principle.
n = int(input("enter the number of vertices in the graph: "))

print("enter the adjacency matrix where each row seperated by spaces:")


graph =[]
for i in range(n):
row = input().split()
graph.append([int(x) for x in row])

source = int(input("Enter the source vertex: "))

def find_hamiltonian_cycles(graph):
n =len(graph)
start_vertex = 0
result = []

#identifying cycles
def hamiltonian_cycle(path):
if len(path) == n and graph[path[-1]][path[0]] == 1:
result.append(path[:])
return

last_vertex = path[-1]
for v in range(n):
if v not in path and graph[last_vertex][v] == 1:
hamiltonian_cycle(path + [v])

hamiltonian_cycle([start_vertex])
return result

cycles = find_hamiltonian_cycles(graph)

if cycles:
print("hamiltonian cycles found:")
for cycle in cycles:
cycle_str = " -> ".join([str(vertex) for vertex in cycle])
print(cycle_str + " -> " + str(cycle[0]))

else:
print("no hamiltonian cycle found")

Output
enter the number of vertices in the graph: 5
enter the adjacency matrix where each row seperated by spaces:
0 1 0 1 0
1 0 0 1 0
0 1 0 0 1
1 1 0 0 1
1 1 1 1 0
Enter the source vertex: 1
hamiltonian cycles found: 0 -> 3 -> 4 -> 2 -> 1 -> 0

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 13


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

7.Implement in c/c++/python, 0/1 knapsack problem using

(a) Dynamic Programming


#input
weight=[10,20,30]
profit=[60,100,120]
capacity=40
n=len(profit)
defDP_Knapsack(capacity,weight,profit,n):
K=[[0forxinrange(capacity+1)]forxinrange(n+1)]

foriinrange(n+1):
forwinrange(capacity+1):
ifi==0orw==0:
K[i][w]=0
elifweight[i-1]<=w:
K[i][w]=max(profit[i-1]+K[i-1][w-weight[i-1]],K[i-1][w])
else:
K[i][w]=K[i-1][w]
returnK[n][capacity]
max_profit=DP_Knapsack(capacity,weight,profit,n)
print("maxprofitearned=",max_profit)

output
maxprofitearned=180
n=int(input("enterthenumberofitems:"))
print("entertheweightandprofitforeachitem:")

weight=[]
profit=[]
foriinrange(n):
w=int(input("weightofitem{}:".format(i+1)))
p=int(input("profitofitem{}:".format(i+1)))
weight.append(w)
profit.append(p)

capacity=int(input("entertyhecapacityoftheknapsack:"))
defDP_Knapsack(capacity,weight,profit,n):
k=[[0forxinrange(capacity+1)]forxinrange(n+1)]

foriinrange(n+1):
forwinrange(capacity+1):
ifi==0orw==0:
k[i][w]=0
elifweight[i-1]<=w:
k[i][w]=max(profit[i-1]+k[i-1][w-weight[i-1]],k[i-1][w])
else:
k[i][w]=k[i-1][w]
returnk[n][capacity]
max_profit=DP_Knapsack(capacity,weight,profit,n)
print("maxprofitearned=",max_profit)

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 14


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

Output

Enter the number of items:3


enter the weight and profit
for each item: weight of
item 1:10
profit of item 1:20 weight of item 2:30 profit of item2:100 weight of item 3:30 profit of item3:120
enter the capacity of the knapsack:50 max profit earned =140

(b) GREEDY METHOD


weight = [10,20,30]
profit = [60,100,120]
capacity = 40
n = len(profit)
def greedy_Knapsack(capacity, weight, profit, n):
#compute profit/weight ratio
ratio = [(profit[i]/weight[i],weight[i],profit[i]) for i in range(n)]

ratio.sort(reverse = True,key = lambda x: x[0])


total_profit = 0
current_weight = 0
for ratio_value,w,p in ratio:
if current_weight +w <= capacity:
total_profit = total_profit + p
current_weight = current_weight + w
else:
remaining_capacity = capacity - current_weight
total_profit = total_profit + ratio_value * remaining_capacity
break

return total_profit
max_profit = greedy_Knapsack(capacity, weight, profit ,n)
print("max profit earned = ", max_profit)
n = int(input("enter the number of items:"))
print("enter the weight and profit for each item:")

weight = []
profit = []
for i in range(n):
w = int(input("weight of item {}:".format(i+1)))
p = int(input("profit of item {}:".format(i+1)))
weight.append(w)
profit.append(p)
def greedy_Knapsack(capacity, weight, profit, n):
ratio = [(profit[i]/weight[i],weight[i],profit[i]) for i in range(n)]

ratio.sort(reverse = True,key = lambda x: x[0])


total_profit = 0
current_weight = 0
for ratio_value,w,p in ratio:

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 15


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

if current_weight +w <= capacity:


total_profit = total_profit + p
current_weight = current_weight + w
else:
remaining_capacity = capacity - current_weight
total_profit = total_profit + ratio_value * remaining_capacity
break

return total_profit
max_profit = greedy_Knapsack(capacity, weight, profit ,n)
print("max profit earned(Greedy Approach) = ", max_profit)
Output

enter the number of items:3


enter the weight and profit
for each item:weight of
item 1:10
profit of item 1:60 weight of item 2:20 profit of item 2:100
weight of item 3:30 profit of item 3:120
max profit earned(Greedy Approach) = 200.0

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 16


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

8. From a given vertex in a weighted connected gragh ,find shortest paths to other vertices
using Dijkstra’s algorithem .Write the program in c/c++/python.

Output

Shortest distance from node to each node :


Vertex 0 Distance 0
Vertex 1 Distance 9
Vertex 2 Distance 13
Vertex 3Distance 7
Vertex 4 Distance 19

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 17


DESIGN AND ANALYSIS OF ALGORITHEMS(BUEL404)

DEPT OF ECE ,VTU’s CPGS KALABURAGI Page 18

You might also like