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

DSAI Lab Programs

DSAI Lab Programs

Uploaded by

Thirandasu
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views

DSAI Lab Programs

DSAI Lab Programs

Uploaded by

Thirandasu
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 49

1) #Write a Python program that takes two arrays a and b of length n storing int values,

and returns the dot product of a and b. That is, it returns an array c of length n such that
c[i]=a[i]·b[i],

for i = 0,...,n-1.

def dot_product(v1,v2):

return sum(x*y for x,y in zip(v1,v2))

print(dot_product([1,2,3],[3,5,7]))

O/P:

34
2) #Write a python program to implement Tower of Hanoi Puzzle.

def TowerOfHanoi(n , source, destination, auxiliary):

if n==1:

print ("Move disk 1 from source",source,"to destination",destination)

return

TowerOfHanoi(n-1, source, auxiliary, destination)

print ("Move disk",n,"from source",source,"to destination",destination)

TowerOfHanoi(n-1, auxiliary, destination, source)

-----------------------------------------------------------------------

def tower_of_hanoi(disks, source, auxiliary, target):

if(disks == 1):

print('Move disk 1 from rod {} to rod {}.'.format(source, target))

return

# function call itself

tower_of_hanoi(disks - 1, source, target, auxiliary)

print('Move disk {} from rod {} to rod {}.'.format(disks, source, target))

tower_of_hanoi(disks - 1, auxiliary, source, target)

disks = int(input('Enter the number of disks: '))

# We are referring source as A, auxiliary as B, and target as

-----------------------------------------------------------------------

Enter the number of disks: 1

-----------------------------------------------------------------------

def hanoi(disks, source, auxiliary, target):

if disks == 1:

print('Move disk 1 from peg {} to peg {}.'.format(source, target))

return

hanoi(disks - 1, source, target, auxiliary)

print('Move disk {} from peg {} to peg {}.'.format(disks, source, target))

hanoi(disks - 1, auxiliary, source, target)

disks = int(input('Enter number of disks: '))


hanoi(disks, 'A', 'B', 'C')

-----------------------------------------------------------------------

O/P:

Enter number of disks: 2

Move disk 1 from peg A to peg B.

Move disk 2 from peg A to peg C.

Move disk 1 from peg B to peg C.

3)Write a python program to implement the memory allocation in a dynamic environment


using Dynamic Array.
import ctypes

class DynamicArray(object):

def __init__(self):

self.n = 0 # Count actual elements (Default is 0)

self.capacity = 1 # Default Capacity

self.A = self.make_array(self.capacity)

def __len__(self):

return self.n

def __getitem__(self, k):

if not 0 <= k <self.n:

# Check it k index is in bounds of array

return IndexError('K is out of bounds !')

return self.A[k] # Retrieve from the array at index k

def append(self, ele):

if self.n == self.capacity:

# Double capacity if not enough room

self._resize(2 * self.capacity)

self.A[self.n] = ele # Set self.n index to element

self.n += 1

def insertAt(self,item,index):

if index<0 or index>self.n:

print("please enter appropriate index..")

return

if self.n==self.capacity:

self._resize(2*self.capacity)

for i in range(self.n-1,index-1,-1):

self.A[i+1]=self.A[i]

self.A[index]=item

self.n+=1

def delete(self):
if self.n==0:

print("Array is empty deletion not Possible")

return

self.A[self.n-1]=0

self.n-=1

def removeAt(self,index):

if self.n==0:

print("Array is empty deletion not Possible")

return

if index<0 or index>=self.n:

return IndexError("Index out of bound....deletion not possible")

if index==self.n-1:

self.A[index]=0

self.n-=1

return

for i in range(index,self.n-1):

self.A[i]=self.A[i+1]

self.A[self.n-1]=0

self.n-=1

def _resize(self, new_cap):

B = self.make_array(new_cap) # New bigger array

for k in range(self.n): # Reference all existing values

B[k] = self.A[k]

self.A = B # Call A the new bigger array

self.capacity = new_cap # Reset the capacity


def make_array(self, new_cap):

return (new_cap * ctypes.py_object)()

# Instantiate

arr = DynamicArray()

# Append new element

arr.append(1)

len(arr)

arr.insertAt(12,0)

len(arr)

for i in range(len(arr)):

print(arr[i],end="")

O/P:

121

4) #Write a python program to determine if a strings has more vowels then consonants.

str1 = input("Please Enter Your Own String : ")

vowels = 0

consonants = 0

str1.lower()
for i in str1:

if(i == 'a' or i == 'e' or i == 'i' or i == 'o' or i == 'u'):

vowels = vowels + 1

else:

consonants = consonants + 1

print("Total Number of Vowels in this String = ", vowels)

print("Total Number of Consonants in this String = ", consonants)

--------------------------------------------------------------------------------

O/P:

Please Enter Your Own String : 5

Total Number of Vowels in this String = 0

Total Number of Consonants in this String = 1

5) #Write a python program to implement parentheses matching and HTML tags using
array based stack.

#balanced paranthesis and HTML tags is in expression

open_list=["[","{","(","<"]

close_list=["]","}",")",">"]

#Function to check paranthesis and HTML tags

def check(mystr):

stack = []
for i in mystr:

if i in open_list:

stack.append(i)

elif i in close_list:

pos=close_list.index(i)

if((len(stack)>0) and (open_list[pos]==stack[len(stack)-1])):

stack.pop()

else:

return "Given string is unbalanced"

if len(stack)==0:

return "Given string is balanced"

else:

return "Given string is unbalanced"

string="{<[]{()}>}"

print(string, "_",check(string))

string="[{<}{}[>]]"

print(string, "_",check(string))

string = "{ [(]"

print(string, "_",check(string))

--------------------------------

O/P:

{<[]{()}>} _ Given string is balanced

[{<}{}[>]] _ Given string is unbalanced

{ [(] _ Given string is unbalanced

6) #Write a python program to implement Insertion Sort algorithm using arrays.

def insert_of_sort (list1):

for i in range(1, len(list1)):

value=list1[i]

j=i-1

while j>=0 and value < list1[j]:

list1[j+1]=list1[j]

j-=1

list1[j+1]=value
return list1

list1 = [10,5,13,8,2]

print("The unsorted list is" , list1)

print("The sorted list is" , insert_of_sort(list1))

O/P:

The unsorted list is [10, 5, 13, 8, 2]

The sorted list is [2, 5, 8, 10, 13]

7) #Write a python program to implement Tic- Toc- Toe game using two dimensional
arrays.

def main():

# The main function

introduction = intro()

board = create_grid()

pretty = printPretty(board)

symbol_1, symbol_2 = sym()

full = isFull(board, symbol_1, symbol_2) # The function that starts the game is also in here.

def intro():
# This function introduces the rules of the game Tic Tac Toe

print("Hello! Welcome to Pam's Tic Tac Toe game!")

print("\n")

print("Rules: Player 1 and player 2, represented by X and O, take turns "

"marking the spaces in a 3*3 grid. The player who succeeds in placing "

"three of their marks in a horizontal, vertical, or diagonal row wins.")

print("\n")

input("Press enter to continue.")

print("\n")

def create_grid():

# This function creates a blank playboard

print("Here is the playboard: ")

board = [[" ", " ", " "],

[" ", " ", " "],

[" ", " ", " "]]

return board

def sym():

# This function decides the players' symbols

symbol_1 = input("Player 1, do you want to be X or O? ")

if symbol_1 == "X":

symbol_2 = "O"

print("Player 2, you are O. ")

else:

symbol_2 = "X"

print("Player 2, you are X. ")

input("Press enter to continue.")

print("\n")

return (symbol_1, symbol_2)

def startGamming(board, symbol_1, symbol_2, count):

# This function starts the game.


# Decides the turn

if count % 2 == 0:

player = symbol_1

elif count % 2 == 1:

player = symbol_2

print("Player "+ player + ", it is your turn. ")

row = int(input("Pick a row:"

"[upper row: enter 0, middle row: enter 1, bottom row: enter 2]:"))

column = int(input("Pick a column:"

"[left column: enter 0, middle column: enter 1, right column enter 2]"))

# Check if players' selection is out of range

while (row > 2 or row < 0) or (column > 2 or column < 0):

outOfBoard(row, column)

row = int(input("Pick a row[upper row:"

"[enter 0, middle row: enter 1, bottom row: enter 2]:"))

column = int(input("Pick a column:"

"[left column: enter 0, middle column: enter 1, right column enter 2]"))

# Check if the square is already filled

while (board[row][column] == symbol_1)or (board[row][column] == symbol_2):

filled = illegal(board, symbol_1, symbol_2, row, column)

row = int(input("Pick a row[upper row:"

"[enter 0, middle row: enter 1, bottom row: enter 2]:"))

column = int(input("Pick a column:"

"[left column: enter 0, middle column: enter 1, right column enter 2]"))

# Locates player's symbol on the board

if player == symbol_1:

board[row][column] = symbol_1

else:

board[row][column] = symbol_2
return (board)

def isFull(board, symbol_1, symbol_2):

count = 1

winner = True

# This function check if the board is full

while count < 10 and winner == True:

gaming = startGamming(board, symbol_1, symbol_2, count)

pretty = printPretty(board)

if count == 9:

print("The board is full. Game over.")

if winner == True:

print("There is a tie. ")

# Check if here is a winner

winner = isWinner(board, symbol_1, symbol_2, count)

count += 1

if winner == False:

print("Game over.")

# This is function gives a report

report(count, winner, symbol_1, symbol_2)

def outOfBoard(row, column):

# This function tells the players that their selection is out of range

print("Out of boarder. Pick another one. ")

def printPretty(board):

# This function prints the board nice!

rows = len(board)

cols = len(board)

print("---+---+---")
for r in range(rows):

print(board[r][0], " |", board[r][1], "|", board[r][2])

print("---+---+---")

return board

def isWinner(board, symbol_1, symbol_2, count):

# This function checks if any winner is winning

winner = True

# Check the rows

for row in range (0, 3):

if (board[row][0] == board[row][1] == board[row][2] == symbol_1):

winner = False

print("Player " + symbol_1 + ", you won!")

elif (board[row][0] == board[row][1] == board[row][2] == symbol_2):

winner = False

print("Player " + symbol_2 + ", you won!")

# Check the columns

for col in range (0, 3):

if (board[0][col] == board[1][col] == board[2][col] == symbol_1):

winner = False

print("Player " + symbol_1 + ", you won!")

elif (board[0][col] == board[1][col] == board[2][col] == symbol_2):

winner = False

print("Player " + symbol_2 + ", you won!")

# Check the diagnoals

if board[0][0] == board[1][1] == board[2][2] == symbol_1:

winner = False

print("Player " + symbol_1 + ", you won!")

elif board[0][0] == board[1][1] == board[2][2] == symbol_2:

winner = False

print("Player " + symbol_2 + ", you won!")

elif board[0][2] == board[1][1] == board[2][0] == symbol_1:

winner = False

print("Player " + symbol_1 + ", you won!")


elif board[0][2] == board[1][1] == board[2][0] == symbol_2:

winner = False

print("Player " + symbol_2 + ", you won!")

return winner

def illegal(board, symbol_1, symbol_2, row, column):

print("The square you picked is already filled. Pick another one.")

def report(count, winner, symbol_1, symbol_2):

print("\n")

input("Press enter to see the game summary. ")

if (winner == False) and (count % 2 == 1 ):

print("Winner : Player " + symbol_1 + ".")

elif (winner == False) and (count % 2 == 0 ):

print("Winner : Player " + symbol_2 + ".")

else:

print("There is a tie. ")

# Call Main

main()

----------------------------------------------------------------------------

O/P:

Hello! Welcome to Pam's Tic Tac Toe game!

Rules: Player 1 and player 2, represented by X and O, take turns marking the spaces in a 3*3 grid. The player who
succeeds in placing three of their marks in a horizontal, vertical, or diagonal row wins.

Press enter to continue.5

Here is the playboard:

---+---+---

| |

---+---+---

| |

---+---+---

| |

---+---+---

Player 1, do you want to be X or O? X

Player 2, you are O.


Press enter to continue.o

Player O, it is your turn.

Pick a row:[upper row: enter 0, middle row: enter 1, bottom row: enter 2]:1

Pick a column:[left column: enter 0, middle column: enter 1, right column enter 2]2

---+---+---

| |

---+---+---

| |O

---+---+---

| |

---+---+---

Player X, it is your turn.

Pick a row:[upper row: enter 0, middle row: enter 1, bottom row: enter 2]:

8) #write a python program to implement stack abstract data type using Python List

stack = []

#Function to print top element of stack

def top(stack):

if stack!=[]:

print(stack[-1]+ "is top element")

else:

print("stack is empty")

#Function to print size of stack

def size(stack):

print("size of stack is" + str(len(stack)))

def empty(stack):

if stack==[]:

print("True")

else:

print("False")
#Append function is used to push element in the stack

stack.append('a')

stack.append('b')

stack.append('c')

size(stack)

print(stack)

top(stack)

#POP function to POP element from stack in LIFO order

print(stack.pop()+ "is popped")

print(stack)

empty(stack)

print(stack.pop()+ "is popped")

print(stack.pop()+ "is popped")

print(stack)

empty(stack)

O/P:

size of stack is3

['a', 'b', 'c']

cis top element

cis popped

['a', 'b']

False

bis popped

ais popped

[]

True
9) #write a python program to implement Round robin scheduler using circular linked list

class RoundRobin:

def processData(self, no_of_processes):

process_data = []

for i in range(no_of_processes):

temporary = []

process_id = int(input("Enter Process ID: "))

arrival_time = int(input(f"Enter Arrival Time for Process {process_id}: "))

burst_time = int(input(f"Enter Burst Time for Process {process_id}: "))

temporary.extend([process_id, arrival_time, burst_time, 0, burst_time])

process_data.append(temporary)

time_slice = int(input("Enter Time Slice: "))

RoundRobin.schedulingProcess(self, process_data, time_slice)

def schedulingProcess(self, process_data, time_slice):

start_time = []

exit_time = []

executed_process = []

ready_queue = []

s_time = 0
process_data.sort(key=lambda x: x[1])

while 1:

normal_queue = []

temp = []

for i in range(len(process_data)):

if process_data[i][1] <= s_time and process_data[i][3] == 0:

present = 0

if len(ready_queue) != 0:

for k in range(len(ready_queue)):

if process_data[i][0] == ready_queue[k][0]:

present = 1

if present == 0:

temp.extend([process_data[i][0], process_data[i][1], process_data[i][2], process_data[i][4]])

ready_queue.append(temp)

temp = []

if len(ready_queue) != 0 and len(executed_process) != 0:

for k in range(len(ready_queue)):

if ready_queue[k][0] == executed_process[len(executed_process) - 1]:

ready_queue.insert((len(ready_queue) - 1), ready_queue.pop(k))

elif process_data[i][3] == 0:

temp.extend([process_data[i][0], process_data[i][1], process_data[i][2], process_data[i][4]])

normal_queue.append(temp)

temp = []

if len(ready_queue) == 0 and len(normal_queue) == 0:

break

if len(ready_queue) != 0:

if ready_queue[0][2] > time_slice:

start_time.append(s_time)

s_time = s_time + time_slice

e_time = s_time

exit_time.append(e_time)

executed_process.append(ready_queue[0][0])

for j in range(len(process_data)):

if process_data[j][0] == ready_queue[0][0]:
break

process_data[j][2] = process_data[j][2] - time_slice

ready_queue.pop(0)

elif ready_queue[0][2] <= time_slice:

start_time.append(s_time)

s_time = s_time + ready_queue[0][2]

e_time = s_time

exit_time.append(e_time)

executed_process.append(ready_queue[0][0])

for j in range(len(process_data)):

if process_data[j][0] == ready_queue[0][0]:

break

process_data[j][2] = 0

process_data[j][3] = 1

process_data[j].append(e_time)

ready_queue.pop(0)

elif len(ready_queue) == 0:

if s_time < normal_queue[0][1]:

s_time = normal_queue[0][1]

if normal_queue[0][2] > time_slice:

start_time.append(s_time)

s_time = s_time + time_slice

e_time = s_time

exit_time.append(e_time)

executed_process.append(normal_queue[0][0])

for j in range(len(process_data)):

if process_data[j][0] == normal_queue[0][0]:

break

process_data[j][2] = process_data[j][2] - time_slice

elif normal_queue[0][2] <= time_slice:

start_time.append(s_time)

s_time = s_time + normal_queue[0][2]

e_time = s_time

exit_time.append(e_time)
executed_process.append(normal_queue[0][0])

for j in range(len(process_data)):

if process_data[j][0] == normal_queue[0][0]:

break

process_data[j][2] = 0

process_data[j][3] = 1

process_data[j].append(e_time)

t_time = RoundRobin.calculateTurnaroundTime(self, process_data)

w_time = RoundRobin.calculateWaitingTime(self, process_data)

RoundRobin.printData(self, process_data, t_time, w_time, executed_process)

def calculateTurnaroundTime(self, process_data):

total_turnaround_time = 0

for i in range(len(process_data)):

turnaround_time = process_data[i][5] - process_data[i][1]

total_turnaround_time = total_turnaround_time + turnaround_time

process_data[i].append(turnaround_time)

average_turnaround_time = total_turnaround_time / len(process_data)

return average_turnaround_time

def calculateWaitingTime(self, process_data):

total_waiting_time = 0

for i in range(len(process_data)):

waiting_time = process_data[i][6] - process_data[i][4]

total_waiting_time = total_waiting_time + waiting_time

process_data[i].append(waiting_time)

average_waiting_time = total_waiting_time / len(process_data)

return average_waiting_time

def printData(self, process_data, average_turnaround_time, average_waiting_time, executed_process):

process_data.sort(key=lambda x: x[0])

print("Process_ID Arrival_Time Rem_Burst_Time Completed Original_Burst_Time Completion_Time


Turnaround_Time Waiting_Time")

for i in range(len(process_data)):
for j in range(len(process_data[i])):

print(process_data[i][j], end=" ")

print()

print(f'Average Turnaround Time: {average_turnaround_time}')

print(f'Average Waiting Time: {average_waiting_time}')

print(f'Sequence of Processes: {executed_process}')

if __name__ == "__main__":

no_of_processes = int(input("Enter number of processes: "))

rr = RoundRobin()

rr.processData(no_of_processes)

O/P:

Enter number of processes: 2

Enter Process ID: 34

Enter Arrival Time for Process 34: 1

Enter Burst Time for Process 34: 3

Enter Process ID: 45

Enter Arrival Time for Process 45: 2

Enter Burst Time for Process 45: 34

Enter Time Slice: 2

Process_ID Arrival_Time Rem_Burst_Time Completed Original_Burst_Time Completion_Time Turnaround_Time


Waiting_Time

34 1 0 1
3 6 5
2

45 2 0 1
34 38 36
2

Average Turnaround Time: 20.5

Average Waiting Time: 2.0

Sequence of Processes: [34, 45, 34, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45]
10) Write a python program to implement Binary Tree Traversal Techniques for Tic-Tac-
Toe game playing using breadth-first traversal order.

# importing all necessary libraries

import numpy as np

import random

from time import sleep

# Creates an empty board

def create_board():

return(np.array([[0, 0, 0],

[0, 0, 0],

[0, 0, 0]]))

# Check for empty places on board

def possibilities(board):

l = []

for i in range(len(board)):

for j in range(len(board)):

if board[i][j] == 0:

l.append((i, j))

return(l)

# Select a random place for the player

def random_place(board, player):

selection = possibilities(board)

current_loc = random.choice(selection)

board[current_loc] = player
return(board)

# Checks whether the player has three

# of their marks in a horizontal row

def row_win(board, player):

for x in range(len(board)):

win = True

for y in range(len(board)):

if board[x, y] != player:

win = False

continue

if win == True:

return(win)

return(win)

# Checks whether the player has three

# of their marks in a vertical row

def col_win(board, player):

for x in range(len(board)):

win = True

for y in range(len(board)):

if board[y][x] != player:

win = False

continue

if win == True:

return(win)

return(win)

# Checks whether the player has three

# of their marks in a diagonal row

def diag_win(board, player):

win = True

y=0

for x in range(len(board)):

if board[x, x] != player:

win = False

if win:
return win

win = True

if win:

for x in range(len(board)):

y = len(board) - 1 - x

if board[x, y] != player:

win = False

return win

# Evaluates whether there is

# a winner or a tie

def evaluate(board):

winner = 0

for player in [1, 2]:

if (row_win(board, player) or

col_win(board, player) or

diag_win(board, player)):

winner = player

if np.all(board != 0) and winner == 0:

winner = -1

return winner

# Main function to start the game

def play_game():

board, winner, counter = create_board(), 0, 1

print(board)

sleep(2)

while winner == 0:

for player in [1, 2]:

board = random_place(board, player)

print("Board after " + str(counter) + " move")

print(board)

sleep(2)

counter += 1

winner = evaluate(board)

if winner != 0:
break

return(winner)

# Driver Code

print("Winner is: " + str(play_game()))

O/P:

[[0 0 0]

[0 0 0]

[0 0 0]]

Board after 1 move

[[1 0 0]

[0 0 0]

[0 0 0]]

Board after 2 move

[[1 0 0]

[0 0 2]

[0 0 0]]

Board after 3 move

[[1 0 0]

[0 0 2]

[1 0 0]]

Board after 4 move

[[1 0 2]

[0 0 2]

[1 0 0]]

Board after 5 move

[[1 0 2]

[0 0 2]

[1 0 1]]

Board after 6 move

[[1 0 2]

[2 0 2]

[1 0 1]]
Board after 7 move

[[1 0 2]

[2 0 2]

[1 1 1]]

Winner is: 1

11) Write a python program to implement Euler Tours traversal to find order of cities in a
traveling sales man problem.

# Python3 program to implement traveling salesman


# problem using naive approach.
from sys import maxsize
from itertools import permutations
V=4
# implementation of traveling Salesman Problem
def travellingSalesmanProblem(graph, s):

# store all vertex apart from source vertex


vertex = []
for i in range(V):
if i != s:
vertex.append(i)

# store minimum weight Hamiltonian Cycle


min_path = maxsize
next_permutation=permutations(vertex)
for i in next_permutation:

# store current Path weight(cost)


current_pathweight = 0

# compute current path weight


k=s
for j in i:
current_pathweight += graph[k][j]
k=j
current_pathweight += graph[k][s]

# update minimum
min_path = min(min_path, current_pathweight)

return min_path

# Driver Code
if __name__ == "__main__":

# matrix representation of graph


graph = [[0, 10, 15, 20], [10, 0, 35, 25],
[15, 35, 0, 30], [20, 25, 30, 0]]
s=0
print(travellingSalesmanProblem(graph, s))

O/P:

80
12) Write a python program to evaluate an arithmetic expression using expression tree.

class node:
def __init__(self, value):
self.left = None
self.data = value
self.right = None
def evaluateExpressionTree(root):

# empty tree
if root is None:
return 0

# leaf node
if root.left is None and root.right is None:
return int(root.data)

# evaluate left tree


left_sum = evaluateExpressionTree(root.left)

# evaluate right tree


right_sum = evaluateExpressionTree(root.right)

# check which operation to apply


if root.data == '+':
return left_sum + right_sum

elif root.data == '-':


return left_sum - right_sum

elif root.data == '*':


return left_sum * right_sum

else:
return left_sum // right_sum

# Driver function to test above problem


if __name__ == '__main__':

# creating a sample tree


root = node('+')
root.left = node('*')
root.left.left = node('5')
root.left.right = node('-4')
root.right = node('-')
root.right.left = node('100')
root.right.right = node('20')
print (evaluateExpressionTree(root))

root = None

# creating a sample tree


root = node('+')
root.left = node('*')
root.left.left = node('5')
root.left.right = node('4')
root.right = node('-')
root.right.left = node('100')
root.right.right = node('/')
root.right.right.left = node('20')
root.right.right.right = node('2')
print (evaluateExpressionTree(root))

O/P:
60
110
13) Write a python program to implement KMP (Knuth-Morris-Pratt) Algorithm to match
the given pattern of characters.

def KMPSearch(pat, txt):

M=len(pat)

N=len(txt)

#Create lps[] that will hold longest prefix suffix

#values for pattern

lps=[0]*M

j=0#index for pat[]

#preprocess the pattern(calculate lps[] array)

computeLPSArray(pat, M, lps)

i=0 #index for txt[]

while i < N:

if pat[j]==txt[i]:

i += 1

j += 1

if j == M:

print("Found pattern at index", str(i-j))

j=lps[j-1]

#mismatch after j matches

elif i < N and pat[j]!=txt[i]:

#Do not match lps[0...lps[j-1]] characters,

#they will macth anyway

if j!=0:

j=lps[j-1]

else:

i += 1

def computeLPSArray(pat, M, lps):

len = 0 # length of the previous longest prefix suffix


lps[0] #lps[0] is always 0

i=1

#the loop calculates lps[i] for i=1 to M-1

while i < M:

if pat[i] ==pat[len]:

len += 1

lps[i]=len

i += 1

else:

#This is tricky. Consider the example.

#AAACAAAA and i=7. The idea is similar

#to search step.

if len !=0:

len=lps[len-1]

#Also, note that we do not increment i here

else:

lps[i]=0

i += 1

txt="ABABDABACDABABCABAB"

pat="ABABCABA"

KMPSearch(pat, txt)

16) DFS

def dfs(graph,start,visited=None):

if visited is None:

visited=set()

visited.add(start)

print(start)

for next in graph[start]-visited:

dfs(graph,next,visited)

return visited
graph = {'0':set(['1','2','3']),'1':set(['2','0']),'2':set(['0','4']),'3':set(['0']),'4':set(['2'])}

dfs(graph,'0')

O/P:

{'0', '1', '2', '3', '4'}


14) Writeapythonprogramtorepresentapriorityqueueenvironmentandagenttosupportthefoll
owingsearchingstrategies:
a. A*Search
b. Best-firstsearch
c. Alpha-Betacutoffsearch

a) A* Search

def aStarAlgo(start_node, stop_node):

open_set = set(start_node)

closed_set = set()

g = {} #store distance from starting node

parents = {}# parents contains an adjacency map of all nodes

#ditance of starting node from itself is zero

g[start_node] = 0

#start_node is root node i.e it has no parent nodes

#so start_node is set to its own parent node

parents[start_node] = start_node

while len(open_set) > 0:

n = None

#node with lowest f() is found

for v in open_set:

if n == None or g[v] + heuristic(v) < g[n] + heuristic(n):

n=v

if n == stop_node or Graph_nodes[n] == None:

pass

else:

for (m, weight) in get_neighbors(n):

#nodes 'm' not in first and last set are added to first

#n is set its parent

if m not in open_set and m not in closed_set:

open_set.add(m)

parents[m] = n

g[m] = g[n] + weight


#for each node m,compare its distance from start i.e g(m) to the

#from start through n node

else:

if g[m] > g[n] + weight:

#update g(m)

g[m] = g[n] + weight

#change parent of m to n

parents[m] = n

#if m in closed set,remove and add to open

if m in closed_set:

closed_set.remove(m)

open_set.add(m)

if n == None:

print('Path does not exist!')

return None

# if the current node is the stop_node

# then we begin reconstructin the path from it to the start_node

if n == stop_node:

path = []

while parents[n] != n:

path.append(n)

n = parents[n]

path.append(start_node)

path.reverse()

print('Path found: {}'.format(path))

return path
# remove n from the open_list, and add it to closed_list

# because all of his neighbors were inspected

open_set.remove(n)

closed_set.add(n)

print('Path does not exist!')

return None

#define fuction to return neighbor and its distance

#from the passed node

def get_neighbors(v):

if v in Graph_nodes:

return Graph_nodes[v]

else:

return None

#for simplicity we ll consider heuristic distances given

#and this function returns heuristic distance for all nodes

def heuristic(n):

H_dist = {

'A': 11,

'B': 6,

'C': 99,

'D': 1,

'E': 7,

'G': 0,

return H_dist[n]

#Describe your graph here

Graph_nodes = {
'A': [('B', 2), ('E', 3)],

'B': [('C', 1),('G', 9)],

'C': None,

'E': [('D', 6)],

'D': [('G', 1)],

aStarAlgo('A', 'G')

O/P:

Path found: ['A', 'E', 'D', 'G']

['A', 'E', 'D', 'G']

b) Best-first search

from queue import PriorityQueue

v = 14

graph = [[] for i in range(v)]

def best_first_search(actual_src, target, n):

visited = [False] * n

pq = PriorityQueue()

pq.put((0,actual_src))

visited[actual_src] = True

while pq.empty() == False:

u = pq.get()[1]

print(u,end=" ")

if u == target:

break

for v, c in graph[u]:

if visited[v] == False:

visited[v] = True

pq.put((c,v))

print()

def addedge(x,y, cost):


graph[x].append((y,cost))

graph[y].append((x,cost))

addedge(0,1,3)

addedge(0,2,6)

addedge(0,3,5)

addedge(1,4,9)

addedge(1,5,8)

addedge(2,6,12)

addedge(2,7,14)

addedge(3,8,7)

addedge(8,9,5)

addedge(8,10,6)

addedge(9,11,1)

addedge(9,12,10)

addedge(9,13,2)

source = 0

target = 9

best_first_search(source, target, v)

O/P:

15) Writeapythonprogramtodemonstratetheminimaxsearchproceduretothemagicsquare problem.

def generateSquare(n):

# 2-D array with all

# slots set to 0
magicSquare = [[0 for x in range(n)]

for y in range(n)]

# initialize position of 1

i=n/2

j=n-1

# Fill the square by placing values

num = 1

while num <= (n * n):

if i == -1 and j == n: # 3rd condition

j=n-2

i=0

else:

# next number goes out of

# right side of square

if j == n:

j=0

# next number goes

# out of upper side

if i < 0:

i=n-1

if magicSquare[int(i)][int(j)]: # 2nd condition

j=j-2

i=i+1

continue

else:

magicSquare[int(i)][int(j)] = num

num = num + 1

j=j+1

i = i - 1 # 1st condition

# Printing the square

print ("Magic Square for n =", n)

print ("Sum of each row or column",n * (n * n + 1) / 2, "\n")

for i in range(0, n):

for j in range(0, n):


print('%2d ' % (magicSquare[i][j]),end = '')

# To display output

# in matrix form

if j == n - 1:

print()

# Driver Code

# Works only when n is odd

n=int(input("Number of rows of the Magic Square:"))

generateSquare(n)

O/P:

Number of rows of the Magic Square:3

Magic Square for n = 3

Sum of each row or column 15.0

2 7 6

9 5 1

4 3 8

16) Implementation of DFS (Depth First Search).

def dfs(graph,start,visited=None):

if visited is None:

visited=set()

visited.add(start)
print(start)

for next in graph[start]-visited:

dfs(graph,next,visited)

return visited

graph = {'0':set(['1','2','3']),'1':set(['2','0']),'2':set(['0','4']),'3':set(['0']),'4':set(['2'])}

dfs(graph,'0')

O/P:

{'0', '1', '2', '3', '4'}

17) Implementation of AO* search algorithm.

class Graph:

def __init__(self, graph, heuristicNodeList, startNode): #instantiate graph object with graph topology, heuristic
values, start node

self.graph = graph

self.H=heuristicNodeList

self.start=startNode

self.parent={}
self.status={}

self.solutionGraph={}

def applyAOStar(self): # starts a recursive AO* algorithm

self.aoStar(self.start, False)

def getNeighbors(self, v): # gets the Neighbors of a given node

return self.graph.get(v,'')

def getStatus(self,v): # return the status of a given node

return self.status.get(v,0)

def setStatus(self,v, val): # set the status of a given node

self.status[v]=val

def getHeuristicNodeValue(self, n):

return self.H.get(n,0) # always return the heuristic value of a given node

def setHeuristicNodeValue(self, n, value):

self.H[n]=value # set the revised heuristic value of a given node

def printSolution(self):

print("FOR GRAPH SOLUTION, TRAVERSE THE GRAPH FROM THE START NODE:",self.start)

print("------------------------------------------------------------")

print(self.solutionGraph)

print("------------------------------------------------------------")

def computeMinimumCostChildNodes(self, v): # Computes the Minimum Cost of child nodes of a given node v

minimumCost=0

costToChildNodeListDict={}

costToChildNodeListDict[minimumCost]=[]

flag=True

for nodeInfoTupleList in self.getNeighbors(v): # iterate over all the set of child node/s

cost=0
nodeList=[]

for c, weight in nodeInfoTupleList:

cost=cost+self.getHeuristicNodeValue(c)+weight

nodeList.append(c)

if flag==True: # initialize Minimum Cost with the cost of first set of child node/s

minimumCost=cost

costToChildNodeListDict[minimumCost]=nodeList # set the Minimum Cost child node/s

flag=False

else: # checking the Minimum Cost nodes with the current Minimum Cost

if minimumCost>cost:

minimumCost=cost

costToChildNodeListDict[minimumCost]=nodeList # set the Minimum Cost child node/s

return minimumCost, costToChildNodeListDict[minimumCost] # return Minimum Cost and Minimum Cost child
node/s

def aoStar(self, v, backTracking): # AO* algorithm for a start node and backTracking status flag

print("HEURISTIC VALUES :", self.H)

print("SOLUTION GRAPH :", self.solutionGraph)

print("PROCESSING NODE :", v)

print("-----------------------------------------------------------------------------------------")

if self.getStatus(v) >= 0: # if status node v >= 0, compute Minimum Cost nodes of v

minimumCost, childNodeList = self.computeMinimumCostChildNodes(v)

print(minimumCost, childNodeList)

self.setHeuristicNodeValue(v, minimumCost)

self.setStatus(v,len(childNodeList))

solved=True # check the Minimum Cost nodes of v are solved

for childNode in childNodeList:

self.parent[childNode]=v

if self.getStatus(childNode)!=-1:

solved=solved & False

if solved==True: # if the Minimum Cost nodes of v are solved, set the current node status as solved(-1)

self.setStatus(v,-1)

self.solutionGraph[v]=childNodeList # update the solution graph with the solved nodes which may be a
part of solution

if v!=self.start: # check the current node is the start node for backtracking the current node value
self.aoStar(self.parent[v], True) # backtracking the current node value with backtracking status set to
true

if backTracking==False: # check the current call is not for backtracking

for childNode in childNodeList: # for each Minimum Cost child node

self.setStatus(childNode,0) # set the status of child node to 0(needs exploration)

self.aoStar(childNode, False) # Minimum Cost child node is further explored with backtracking status
as false

#for simplicity we ll consider heuristic distances given

print ("Graph - 1")

h1 = {'A': 1, 'B': 6, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 5, 'H': 7, 'I': 7, 'J': 1}

graph1 = {

'A': [[('B', 1), ('C', 1)], [('D', 1)]],

'B': [[('G', 1)], [('H', 1)]],

'C': [[('J', 1)]],

'D': [[('E', 1), ('F', 1)]],

'G': [[('I', 1)]]

G1= Graph(graph1, h1, 'A')

G1.applyAOStar()

G1.printSolution()

O/P:

Graph - 1

HEURISTIC VALUES : {'A': 1, 'B': 6, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 5, 'H': 7, 'I': 7, 'J': 1}

SOLUTION GRAPH : {}

PROCESSING NODE : A

-----------------------------------------------------------------------------------------

10 ['B', 'C']

HEURISTIC VALUES : {'A': 10, 'B': 6, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 5, 'H': 7, 'I': 7, 'J': 1}

SOLUTION GRAPH : {}

PROCESSING NODE : B
-----------------------------------------------------------------------------------------

6 ['G']

HEURISTIC VALUES : {'A': 10, 'B': 6, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 5, 'H': 7, 'I': 7, 'J': 1}

SOLUTION GRAPH : {}

PROCESSING NODE : A

-----------------------------------------------------------------------------------------

10 ['B', 'C']

HEURISTIC VALUES : {'A': 10, 'B': 6, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 5, 'H': 7, 'I': 7, 'J': 1}

SOLUTION GRAPH : {}

PROCESSING NODE : G

-----------------------------------------------------------------------------------------

8 ['I']

HEURISTIC VALUES : {'A': 10, 'B': 6, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 8, 'H': 7, 'I': 7, 'J': 1}

SOLUTION GRAPH : {}

PROCESSING NODE : B

-----------------------------------------------------------------------------------------

8 ['H']

HEURISTIC VALUES : {'A': 10, 'B': 8, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 8, 'H': 7, 'I': 7, 'J': 1}

SOLUTION GRAPH : {}

PROCESSING NODE : A

-----------------------------------------------------------------------------------------

12 ['B', 'C']

HEURISTIC VALUES : {'A': 12, 'B': 8, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 8, 'H': 7, 'I': 7, 'J': 1}

SOLUTION GRAPH : {}

PROCESSING NODE : I

-----------------------------------------------------------------------------------------

0 []

HEURISTIC VALUES : {'A': 12, 'B': 8, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 8, 'H': 7, 'I': 0, 'J': 1}

SOLUTION GRAPH : {'I': []}

PROCESSING NODE : G

-----------------------------------------------------------------------------------------

1 ['I']

HEURISTIC VALUES : {'A': 12, 'B': 8, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 1, 'H': 7, 'I': 0, 'J': 1}

SOLUTION GRAPH : {'I': [], 'G': ['I']}


PROCESSING NODE : B

-----------------------------------------------------------------------------------------

2 ['G']

HEURISTIC VALUES : {'A': 12, 'B': 2, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 1, 'H': 7, 'I': 0, 'J': 1}

SOLUTION GRAPH : {'I': [], 'G': ['I'], 'B': ['G']}

PROCESSING NODE : A

-----------------------------------------------------------------------------------------

6 ['B', 'C']

HEURISTIC VALUES : {'A': 6, 'B': 2, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 1, 'H': 7, 'I': 0, 'J': 1}

SOLUTION GRAPH : {'I': [], 'G': ['I'], 'B': ['G']}

PROCESSING NODE : C

-----------------------------------------------------------------------------------------

2 ['J']

HEURISTIC VALUES : {'A': 6, 'B': 2, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 1, 'H': 7, 'I': 0, 'J': 1}

SOLUTION GRAPH : {'I': [], 'G': ['I'], 'B': ['G']}

PROCESSING NODE : A

-----------------------------------------------------------------------------------------

6 ['B', 'C']

HEURISTIC VALUES : {'A': 6, 'B': 2, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 1, 'H': 7, 'I': 0, 'J': 1}

SOLUTION GRAPH : {'I': [], 'G': ['I'], 'B': ['G']}

PROCESSING NODE : J

-----------------------------------------------------------------------------------------

0 []

HEURISTIC VALUES : {'A': 6, 'B': 2, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 1, 'H': 7, 'I': 0, 'J': 0}

SOLUTION GRAPH : {'I': [], 'G': ['I'], 'B': ['G'], 'J': []}

PROCESSING NODE : C

-----------------------------------------------------------------------------------------

1 ['J']

HEURISTIC VALUES : {'A': 6, 'B': 2, 'C': 1, 'D': 12, 'E': 2, 'F': 1, 'G': 1, 'H': 7, 'I': 0, 'J': 0}

SOLUTION GRAPH : {'I': [], 'G': ['I'], 'B': ['G'], 'J': [], 'C': ['J']}

PROCESSING NODE : A

-----------------------------------------------------------------------------------------

5 ['B', 'C']

FOR GRAPH SOLUTION, TRAVERSE THE GRAPH FROM THE START NODE: A
------------------------------------------------------------

{'I': [], 'G': ['I'], 'B': ['G'], 'J': [], 'C': ['J'], 'A': ['B', 'C']}

18) Implementation of problem-solving using Hill climbing.

import random

def randomSolution(tsp):

cities = list(range(len(tsp)))

solution = []

for i in range(len(tsp)):

randomCity = cities[random.randint(0, len(cities) - 1)]

solution.append(randomCity)

cities.remove(randomCity)

return solution

def routeLength(tsp, solution):

routeLength = 0
for i in range(len(solution)):

routeLength += tsp[solution[i - 1]][solution[i]]

return routeLength

def getNeighbours(solution):

neighbours = []

for i in range(len(solution)):

for j in range(i + 1, len(solution)):

neighbour = solution.copy()

neighbour[i] = solution[j]

neighbour[j] = solution[i]

neighbours.append(neighbour)

return neighbours

def getBestNeighbour(tsp, neighbours):

bestRouteLength = routeLength(tsp, neighbours[0])

bestNeighbour = neighbours[0]

for neighbour in neighbours:

currentRouteLength = routeLength(tsp, neighbour)

if currentRouteLength < bestRouteLength:

bestRouteLength = currentRouteLength

bestNeighbour = neighbour

return bestNeighbour, bestRouteLength

def hillClimbing(tsp):

currentSolution = randomSolution(tsp)

currentRouteLength = routeLength(tsp, currentSolution)

neighbours = getNeighbours(currentSolution)

bestNeighbour, bestNeighbourRouteLength = getBestNeighbour(tsp, neighbours)

while bestNeighbourRouteLength < currentRouteLength:

currentSolution = bestNeighbour

currentRouteLength = bestNeighbourRouteLength

neighbours = getNeighbours(currentSolution)

bestNeighbour, bestNeighbourRouteLength = getBestNeighbour(tsp, neighbours)


return currentSolution, currentRouteLength

def main():

tsp = [

[0, 400, 500, 300],

[400, 0, 300, 500],

[500, 300, 0, 400],

[300, 500, 400, 0]

print(hillClimbing(tsp))

if __name__ == "__main__":

main()

O/P:

([1, 2, 3, 0], 1400)

20) Implementation of Constraint Satisfaction Problem.

# Python3 program to implement greedy

# algorithm for graph coloring

def addEdge(adj, v, w):

adj[v].append(w)

# Note: the graph is undirected

adj[w].append(v)

return adj

# Assigns colors (starting from 0) to all

# vertices and prints the assignment of colors

def greedyColoring(adj, V):


result = [-1] * V

# Assign the first color to first vertex

result[0] = 0;

# A temporary array to store the available colors.

# True value of available[cr] would mean that the

# color cr is assigned to one of its adjacent vertices

available = [False] * V

# Assign colors to remaining V-1 vertices

for u in range(1, V):

# Process all adjacent vertices and

# flag their colors as unavailable

for i in adj[u]:

if (result[i] != -1):

available[result[i]] = True

# Find the first available color

cr = 0

while cr < V:

if (available[cr] == False):

break

cr += 1

# Assign the found color

result[u] = cr

# Reset the values back to false


# for the next iteration

for i in adj[u]:

if (result[i] != -1):

available[result[i]] = False

# Print the result

for u in range(V):

print("Vertex", u, " ---> Color", result[u])

# Driver Code

if __name__ == '__main__':

g1 = [[] for i in range(5)]

g1 = addEdge(g1, 0, 1)

g1 = addEdge(g1, 0, 2)

g1 = addEdge(g1, 1, 2)

g1 = addEdge(g1, 1, 3)

g1 = addEdge(g1, 2, 3)

g1 = addEdge(g1, 3, 4)

print("Coloring of graph 1 ")

greedyColoring(g1, 5)

g2 = [[] for i in range(5)]

g2 = addEdge(g2, 0, 1)

g2 = addEdge(g2, 0, 2)

g2 = addEdge(g2, 1, 2)

g2 = addEdge(g2, 1, 4)

g2 = addEdge(g2, 2, 4)

g2 = addEdge(g2, 4, 3)

print("\nColoring of graph 2")

greedyColoring(g2, 5)

# This code is contributed by mohit kumar 29


O/P:

Coloring of graph 1

Vertex 0 ---> Color 0

Vertex 1 ---> Color 1

Vertex 2 ---> Color 2

Vertex 3 ---> Color 0

Vertex 4 ---> Color 1

Coloring of graph 2

Vertex 0 ---> Color 0

Vertex 1 ---> Color 1

Vertex 2 ---> Color 2

Vertex 3 ---> Color 0

Vertex 4 ---> Color 3

You might also like