JUSTIN VARGHESE 710723104037
Ex.no: 4 Floyd’s Algorithm for All-Pairs Shortest
Date:
Paths
AIM:
To develop a Python program that implements Floyd’s algorithm for solving the All-Pairs Shortest
Paths problem and measures its execution time.
ALGORITHM:
Step 1: Start the program.
Step 2: Import required modules: time, numpy, and ThreadPoolExecutor for parallelism.
Step 3: Define a function to perform the Floyd-Warshall algorithm sequentially.
Step 4: Define a function to perform the Floyd-Warshall algorithm in parallel using threads.
Step 5: Generate a random weighted graph with a given number of vertices.
Step 6: Run the sequential Floyd-Warshall function and record execution time.
Step 7: Run the parallel Floyd-Warshall function and record execution time.
Step 8: Calculate the speed-up achieved by parallel execution over sequential.
Step 9: Display the sequential time, parallel time, and speed-up.
Step 10: End the program.
PROGRAM:
import time import numpy as np from multiprocessing
import Pool, cpu_count, Manager
INF = float('inf')
# Floyd-Warshall Sequential def
floyd_warshall_seq(graph): n
= len(graph)
dist = [row[:] for row in graph]
for k in range(n): for i in
range(n): for j in
range(n):
22UCS404-DESIGN AND ANALYSIS OF ALGORITHMS LABORATORY
JUSTIN VARGHESE 710723104037
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
return dist
# Helper for multiprocessing
def update_row(args): i,
k, shared_dist, n = args
for j in range(n):
shared_dist[i][j] = min(shared_dist[i][j], shared_dist[i][k] + shared_dist[k][j])
return i
# Floyd-Warshall with multiprocessing def
floyd_warshall_parallel(graph):
n = len(graph)
manager = Manager()
shared_dist = manager.list([manager.list(row) for row in graph])
for k in range(n):
args = [(i, k, shared_dist, n) for i in range(n)]
with Pool(cpu_count()) as pool:
pool.map(update_row, args)
return [list(row) for row in shared_dist]
# Random Graph Generator def generate_graph(n,
edge_prob=0.3, max_weight=10):
graph = [[INF if i != j else 0 for j in range(n)] for i in range(n)]
for i in range(n): for j in range(n): if i != j and
np.random.rand() < edge_prob:
graph[i][j] = np.random.randint(1, max_weight)
return graph
# Main Execution if
__name__ == "__main__":
N = 50
22UCS404-DESIGN AND ANALYSIS OF ALGORITHMS LABORATORY
JUSTIN VARGHESE 710723104037
graph = generate_graph(N)
start_seq = time.time()
floyd_warshall_seq(graph) end_seq
= time.time() start_par =
time.time()
floyd_warshall_parallel(graph)
end_par = time.time()
time_seq = end_seq - start_seq
time_par = end_par - start_par
speedup = time_seq / time_par if time_par > 0 else float('inf')
print(f"Sequential Time: {time_seq:.4f} s")
print(f"Parallel Time: {time_par:.4f} s") print(f"Speed-
up: {speedup:.2f}x")
OUTPUT:
22UCS404-DESIGN AND ANALYSIS OF ALGORITHMS LABORATORY
JUSTIN VARGHESE 710723104037
RESULT:
Thus, the Python program that implements Floyd’s algorithm to solve the all-pairs shortest paths
problem has been successfully executed.
Ex.no: 5
Date:
N Queen's problem using Back Tracking
AIM:
To write a Python program that implements N Queen’s problem using Back Tracking.
ALGORITHM:
Step 1: Start the program
Step 2: Read the input value N, representing the size of the chessboard.
Step 3: Initialize a board representation to track queen positions column-wise.
Step 4: Create a function to check if placing a queen at a given row and column is safe.
Step 5: Use a recursive function to attempt placing a queen in each row of the current column.
Step 6: If a safe position is found, place the queen and recursively try to solve for the next
column.
Step 7: If all columns are filled, record the current configuration as a valid solution.
Step 8: After exploring all options, display the total number of valid solutions and print them.
Step 9: End the Program.
PROGRAM:
def print_solution(board, N):
for row in board:
line = "" for
col in range(N):
line += "Q " if row == col else ". "
print(line) print()
def is_safe(board, row, col, N):
for i in range(col):
22UCS404-DESIGN AND ANALYSIS OF ALGORITHMS LABORATORY
JUSTIN VARGHESE 710723104037
if board[i] == row or \
abs(board[i] - row) == abs(i - col):
return False
return True
def solve_n_queens_util(board, col, N, solutions):
if col == N:
solutions.append(board[:])
return
for row in range(N): if
is_safe(board, row, col, N):
board[col] = row
solve_n_queens_util(board, col + 1, N, solutions)
def solve_n_queens(N):
board = [-1] * N solutions
= []
solve_n_queens_util(board, 0, N, solutions)
print(f"Total solutions for {N}-Queens: {len(solutions)}\n")
for sol in solutions: for r in sol: line = ['.'] * N
line[r] = 'Q' print(" ".join(line)) print()
# Driver if __name__ ==
"__main__":
N = int(input("Enter value of N: "))
solve_n_queens(N)
OUTPUT:
22UCS404-DESIGN AND ANALYSIS OF ALGORITHMS LABORATORY
JUSTIN VARGHESE 710723104037
22UCS404-DESIGN AND ANALYSIS OF ALGORITHMS LABORATORY
JUSTIN VARGHESE 710723104037
RESULT:
Thus, the Python program that implements N Queen’s problem using Back Tracking has been
successfully executed.
Ex.no: 6
Date:
AVL Tree Construction
AIM:
To construct an AVL tree using Python, demonstrating self-balancing through LL, RR, LR, and RL
rotations
ALGORITHM:
Step 1: Start the program
Step 2: Define an empty AVL tree.
Step 3: Read the number of elements and the list of input values.
Step 4: For each element, insert it into the AVL tree.
Step 5: During each insertion, update the height of affected nodes.
Step 6: Calculate the balance factor of each node after insertion.
Step 7: Identify the type of imbalance (LL, RR, LR, or RL).
Step 8: Perform appropriate rotations to restore AVL balance.
Step 9: After all insertions, perform an inorder traversal to print elements.
Step 10: Display the total time taken for all insertions.
Step 11: End the Program.
PROGRAM:
import time
class Node: def
__init__(self, k):
self.k = k; self.l = self.r = None; self.h = 1
22UCS404-DESIGN AND ANALYSIS OF ALGORITHMS LABORATORY
JUSTIN VARGHESE 710723104037
def ht(n): return n.h if n else 0
def bal(n): return ht(n.l) - ht(n.r)
def r_rot(y): print(f"Right
Rotation on {y.k}") x, T = y.l,
y.l.r
x.r, y.l = y, T
y.h = 1 + max(ht(y.l), ht(y.r))
x.h = 1 + max(ht(x.l), ht(x.r))
return x
def l_rot(x): print(f"Left
Rotation on {x.k}") y, T = x.r,
x.r.l
y.l, x.r = x, T
x.h = 1 + max(ht(x.l), ht(x.r))
y.h = 1 + max(ht(y.l), ht(y.r))
return y
def insert(n, k):
if not n:
print(f"Inserting
{k}") return Node(k)
if k < n.k:
n.l = insert(n.l, k)
else:
n.r = insert(n.r, k)
n.h = 1 + max(ht(n.l), ht(n.r))
b = bal(n)
# Rotations with step info if b > 1 and
k < n.l.k: print(f"Imbalance at {n.k}
22UCS404-DESIGN AND ANALYSIS OF ALGORITHMS LABORATORY
JUSTIN VARGHESE 710723104037
(LL case)") return r_rot(n) if b < -1
and k > n.r.k: print(f"Imbalance at
{n.k} (RR case)") return l_rot(n) if
b > 1 and k > n.l.k: print(f"Imbalance
at {n.k} (LR case)")
n.l = l_rot(n.l) return r_rot(n)
if b < -1 and k < n.r.k:
print(f"Imbalance at {n.k} (RL case)")
n.r = r_rot(n.r)
return l_rot(n) return n
def inorder(n):
if n:
inorder(n.l)
print(n.k, end=' ')
inorder(n.r)
# Main n = int(input("Enter number of elements:
")) a = list(map(int, input("Enter elements:
").split()))
start =
time.perf_counter() root
= None for x in a: root
= insert(root, x) end =
time.perf_counter()
print("\nAVL Inorder Traversal:") inorder(root)
print(f"\nTime taken: {end - start:.6f} seconds")
OUTPUT:
22UCS404-DESIGN AND ANALYSIS OF ALGORITHMS LABORATORY
JUSTIN VARGHESE 710723104037
22UCS404-DESIGN AND ANALYSIS OF ALGORITHMS LABORATORY
JUSTIN VARGHESE 710723104037
RESULT:
Thus, the Python program that implements AVL tree construction and the speed-up time has been
successfully executed.
22UCS404-DESIGN AND ANALYSIS OF ALGORITHMS LABORATORY