0% found this document useful (0 votes)
31 views49 pages

DSAI Lab Programs

DSAI Lab Programs

Uploaded by

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

DSAI Lab Programs

DSAI Lab Programs

Uploaded by

Thirandasu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
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