Daa File
Daa File
LIST OF EXPERIMENTS
1. Sort a given set of elements using the Quicksort method and determine the time
required to sort the elements.
2. 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.
3. The elements can be read from a file or can be generated using the random number
generator.
4. Implement a parallelized Merge Sort algorithm to sort a given set of elements and
determine the time required to sort the elements.
5. 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.
6. The elements can be read from a file or can be generated using the random number
generator.
10. From a given vertex in a weighted connected graph, find shortest paths to other
vertices using Dijkstra's algorithm.
11. Find Minimum Cost Spanning Tree of a given undirected graph using Kruskal's
algorithm.
12. Print all the nodes reachable from a given starting node in a digraph using BFS
method.
13. Check whether a given graph is connected or not using DFS method.
14. Find Minimum Cost Spanning Tree of a given undirected graph using Prim’s
algorithm.
1. Sort a given set of elements using the Quicksort method and determine the
time required to sort the elements.
import time
def quicksort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quicksort(left) + middle + quicksort(right)
def sort_and_measure_time(arr):
start_time = time.time()
sorted_arr = quicksort(arr)
end_time = time.time()
time_taken = end_time - start_time
return sorted_arr, time_taken
# Example usage:
arr = [3, 6, 8, 10, 1, 2, 1]
sorted_arr, time_taken = sort_and_measure_time(arr)
print(f"Sorted Array: {sorted_arr}")
print(f"Time Taken: {time_taken} seconds")
2. 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.
import time
import numpy as np
import matplotlib.pyplot as plt
def quicksort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quicksort(left) + middle + quicksort(right)
def sort_and_measure_time(arr):
start_time = time.time()
sorted_arr = quicksort(arr)
end_time = time.time()
time_taken = end_time - start_time
return time_taken
def run_experiment(sizes):
times = []
for size in sizes:
arr = np.random.randint(0, 10000, size) # Generate random array
time_taken = sort_and_measure_time(arr)
times.append(time_taken)
return times
import time
import random
import matplotlib.pyplot as plt
def quicksort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quicksort(left) + middle + quicksort(right)
def sort_and_measure_time(arr):
start_time = time.time()
sorted_arr = quicksort(arr)
end_time = time.time()
time_taken = end_time - start_time
return sorted_arr, time_taken
def read_elements_from_file(filename):
with open(filename, 'r') as file:
elements = [int(line.strip()) for line in file]
return elements
def generate_random_elements(n):
return [random.randint(0, 1000000) for _ in range(n)]
for n in test_sizes:
if mode == 'file':
arr = read_elements_from_file(filename)[:n]
else:
arr = generate_random_elements(n)
_, time_taken = sort_and_measure_time(arr)
results.append((n, time_taken))
import time
import random
from concurrent.futures import ProcessPoolExecutor
import matplotlib.pyplot as plt
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 parallel_merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
with ProcessPoolExecutor() as executor:
left_future = executor.submit(merge_sort, arr[:mid])
right_future = executor.submit(merge_sort, arr[mid:])
left = left_future.result()
right = right_future.result()
return merge(left, right)
def sort_and_measure_time(arr):
start_time = time.time()
sorted_arr = parallel_merge_sort(arr)
end_time = time.time()
time_taken = end_time - start_time
return sorted_arr, time_taken
def generate_random_elements(n):
return [random.randint(0, 1000000) for _ in range(n)]
for n in test_sizes:
arr = generate_random_elements(n)
_, time_taken = sort_and_measure_time(arr)
results.append((n, time_taken))
import time
import random
from concurrent.futures import ProcessPoolExecutor
import matplotlib.pyplot as plt
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 parallel_merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
with ProcessPoolExecutor() as executor:
left_future = executor.submit(merge_sort, arr[:mid])
right_future = executor.submit(merge_sort, arr[mid:])
left = left_future.result()
right = right_future.result()
return merge(left, right)
def sort_and_measure_time(arr):
start_time = time.time()
sorted_arr = parallel_merge_sort(arr)
end_time = time.time()
time_taken = end_time - start_time
return sorted_arr, time_taken
def generate_random_elements(n):
return [random.randint(0, 1000000) for _ in range(n)]
# Experiment with different values of n
test_sizes = [10, 100, 1000, 10000, 100000]
results = []
for n in test_sizes:
arr = generate_random_elements(n)
_, time_taken = sort_and_measure_time(arr)
results.append((n, time_taken))
import time
import random
from concurrent.futures import ProcessPoolExecutor
import matplotlib.pyplot as plt
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 parallel_merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
with ProcessPoolExecutor() as executor:
left_future = executor.submit(merge_sort, arr[:mid])
right_future = executor.submit(merge_sort, arr[mid:])
left = left_future.result()
right = right_future.result()
return merge(left, right)
def sort_and_measure_time(arr):
start_time = time.time()
sorted_arr = parallel_merge_sort(arr)
end_time = time.time()
time_taken = end_time - start_time
return sorted_arr, time_taken
for n in test_sizes:
if mode == 'file':
arr = read_elements_from_file(filename, n)
else:
arr = generate_random_elements(n)
_, time_taken = sort_and_measure_time(arr)
results.append((n, time_taken))
def topological_sort(graph):
visited = set()
stack = deque()
def dfs(v):
visited.add(v)
for neighbor in graph[v]:
if neighbor not in visited:
dfs(neighbor)
stack.appendleft(v)
return list(stack)
# Example usage
graph = defaultdict(list)
# Add edges
edges = [
('A', 'C'),
('B', 'C'),
('C', 'E'),
('B', 'D'),
('E', 'F'),
('D', 'F')
]
for u, v in edges:
graph[u].append(v)
def warshall_algorithm(graph):
n = len(graph)
closure = [[0] * n for _ in range(n)]
for i in range(n):
for j in range(n):
closure[i][j] = graph[i][j]
for k in range(n):
for i in range(n):
for j in range(n):
closure[i][j] = closure[i][j] or (closure[i][k] and closure[k][j])
return closure
# Example usage
# Adjacency matrix representation of the graph
# 0: no edge, 1: edge present
graph = [
[1, 1, 0, 0],
[0, 1, 1, 0],
[0, 0, 1, 1],
[0, 0, 0, 1]
]
transitive_closure = warshall_algorithm(graph)
print("Transitive Closure:")
for row in transitive_closure:
print(row)
9. Implement 0/1 Knapsack problem using Dynamic Programming.
return dp[n][capacity]
# Example usage
weights = [1, 2, 3, 8, 7, 4]
values = [20, 5, 10, 40, 15, 25]
capacity = 10
import heapq
while priority_queue:
current_distance, current_vertex = heapq.heappop(priority_queue)
# If a node is reached with a distance larger than the recorded distance, skip it
if current_distance > distances[current_vertex]:
continue
return distances
# Example usage
graph = {
'A': [('B', 1), ('C', 4)],
'B': [('A', 1), ('C', 2), ('D', 5)],
'C': [('A', 4), ('B', 2), ('D', 1)],
'D': [('B', 5), ('C', 1)]
}
start_vertex = 'A'
shortest_paths = dijkstra(graph, start_vertex)
class UnionFind:
def __init__(self, size):
self.parent = list(range(size))
self.rank = [0] * size
if root_u != root_v:
# Union by rank
if self.rank[root_u] > self.rank[root_v]:
self.parent[root_v] = root_u
elif self.rank[root_u] < self.rank[root_v]:
self.parent[root_u] = root_v
else:
self.parent[root_v] = root_u
self.rank[root_u] += 1
mst = []
total_cost = 0
while queue:
current_node = queue.popleft()
return reachable_nodes
# Example usage
graph = defaultdict(list)
# Add edges to the graph
edges = [
('A', 'B'),
('A', 'C'),
('B', 'D'),
('C', 'D'),
('D', 'E'),
('E', 'F')
]
for u, v in edges:
graph[u].append(v)
start_node = 'A'
reachable_nodes = bfs_reachable_nodes(graph, start_node)
def is_connected(graph):
# Get all nodes in the graph
nodes = list(graph.keys())
if not nodes:
return True # An empty graph is considered connected
# Example usage
graph = defaultdict(list)
# Add edges to the graph
edges = [
('A', 'B'),
('A', 'C'),
('B', 'D'),
('C', 'D'),
('E', 'F')
]
for u, v in edges:
graph[u].append(v)
graph[v].append(u) # For undirected graph
is_connected_graph = is_connected(graph)
print("The graph is connected:" if is_connected_graph else "The graph is not connected.")
14. Find Minimum Cost Spanning Tree of a given undirected graph using Prim’s
algorithm.
import heapq
from collections import defaultdict
while priority_queue:
current_cost, u = heapq.heappop(priority_queue)
# Add the edge to the MST if it's not the starting vertex
if current_cost > 0:
mst_edges.append((parent[u], u, current_cost))
start_vertex = 'A'
mst_edges, total_cost = prim(graph, start_vertex)