-----------------------------------------------------AI Assignment-1-----------------------------------------------------------
---------------------------------------------------------BFS-----------------------------------------------------------------------
graph = {
'A': ['B', 'C', "D"],
'B': ['E', "F"],
'C': ['G', "I"],
'D': ["I"],
'E': [],
"F": [],
'G': [],
"I": []
}
def bfs(visit_complete, graph, current_node):
visit_complete.append(current_node)
queue = []
queue.append(current_node)
while queue:
s = queue.pop(0)
print(s)
for neighbour in graph[s]:
if neighbour not in visit_complete:
visit_complete.append(neighbour)
queue.append(neighbour)
bfs([], graph, 'A')
output:
I
----------------------------------------------------------DFS-------------------------------------------------------------------
# Using a Python dictionary to act as an adjacency list
graph = {
'5' : ['3','7'],
'3' : ['2', '4'],
'7' : ['8'],
'2' : [],
'4' : ['8'],
'8' : []
}
visited = set() # Set to keep track of visited nodes of graph.
def dfs(visited, graph, node): #function for dfs
if node not in visited:
print (node)
visited.add(node)
for neighbour in graph[node]:
dfs(visited, graph, neighbour)
# Driver Code
print("Following is the Depth-First Search")
dfs(visited, graph, '5')
output:
Following is the Depth-First Search
7
------------------------------------------------Assignment -2-------------------------------------------------------------------
---------------------------------------------------A * Search--------------------------------------------------------------------
class Node:
def __init__(self, data, level, fval):
self.data = data
self.level = level
self.fval = fval
def generate_child(self):
x, y = self.find(self.data, '_')
""" val_list contains position values for moving the blank space in either
of the 4 directions [up,down,left,right] respectively. """ val_list = [[x, y -
1], [x, y + 1], [x - 1, y], [x + 1, y]]
children = []
for i in val_list:
child = self.shuffle(self.data, x, y, i[0], i[1])
if child is not None:
child_node = Node(child, self.level + 1, 0)
children.append(child_node)
return children
def shuffle(self, puz, x1, y1, x2, y2):
""" Move the blank space in the given direction and if the position value are
out of limits the return None """
if x2 >= 0 and x2 < len(self.data) and y2 >= 0 and y2 <
len(self.data): temp_puz = []
temp_puz = self.copy(puz)
temp = temp_puz[x2][y2]
temp_puz[x2][y2] = temp_puz[x1][y1]
temp_puz[x1][y1] = temp
return temp_puz
else:
return None
def copy(self, root):
""" Copy function to create a similar matrix of the given
node""" temp = []
for i in root:
t = []
for j in i:
t.append(j)
temp.append(t)
return temp
def find(self, puz, x):
""" Specifically used to find the position of the blank space
""" for i in range(0, len(self.data)):
for j in range(0, len(self.data)):
if puz[i][j] == x:
return i, j
class Puzzle:
def __init__(self, size):
""" Initialize the puzzle size by the specified size,open and closed lists to empty
""" self.n = size
self.open = []
self.closed = []
def accept(self):
""" Accepts the puzzle from the user """
puz = []
for i in range(0, self.n):
temp = input().split(" ")
puz.append(temp)
return puz
def f(self, start, goal):
""" Heuristic Function to calculate hueristic value f(x) = h(x) + g(x)
""" return self.h(start.data, goal) + start.level
def h(self, start, goal):
""" Calculates the different between the given puzzles
""" temp = 0
for i in range(0, self.n):
for j in range(0, self.n):
if start[i][j] != goal[i][j] and start[i][j] != '_':
temp += 1
return temp
def process(self):
""" Accept Start and Goal Puzzle state"""
print("Enter the start state matrix \n")
start = self.accept()
print("Enter the goal state matrix \n")
goal = self.accept()
start = Node(start, 0, 0)
start.fval = self.f(start, goal)
""" Put the start node in the open list"""
self.open.append(start)
print("\n\n")
while True:
cur = self.open[0]
print("")
print(" | ")
print(" | ")
print(" \\\'/ \n")
for i in cur.data:
for j in i:
print(j, end=" ")
print("")
""" If the difference between current and goal node is 0 we have reached the
goal node"""
if (self.h(cur.data, goal) == 0):
break
for i in cur.generate_child():
i.fval = self.f(i, goal)
self.open.append(i)
self.closed.append(cur)
del self.open[0]
""" sort the opne list based on f value
""" self.open.sort(key=lambda x: x.fval,
reverse=False)
puz = Puzzle(3)
puz.process()
OUTPUT:-
Enter the start state matrix
123
_46
758
Enter the goal state matrix
123
456
78_
|
\'/
_
4
\'/
5
8
\'/
\'/
1
_
-----------------------------------------------------Assignment -3--------------------------------------------------------------
------------------------------------prime’s Algorithm Minimum Spanning Spaning tree------------------------------
import sys # Library for INT_MAX
class Graph():
def __init__(self, vertices):
self.V = vertices
self.graph = [[0 for column in range(vertices)]
for row in range(vertices)]
# A utility function to print the constructed MST stored in parent[]
def printMST(self, parent):
print ("Edge \tWeight")
for i in range(1, self.V):
print (parent[i], "-", i, "\t", self.graph[i][parent[i]])
# A utility function to find the vertex with
# minimum distance value, from the set of vertices
# not yet included in shortest path tree
def minKey(self, key, mstSet):
# Initialize min value
min = sys.maxsize
for v in range(self.V):
if key[v] < min and mstSet[v] == False:
min = key[v]
min_index = v
return min_index
# Function to construct and print MST for a graph
# represented using adjacency matrix representation
def primMST(self):
# Key values used to pick minimum weight edge in cut
key = [sys.maxsize] * self.V
parent = [None] * self.V # Array to store constructed MST
# Make key 0 so that this vertex is picked as first vertex
key[0] = 0
mstSet = [False] * self.V
parent[0] = -1 # First node is always the roo
for cout in range(self.V):
# Pick the minimum distance vertex from
# the set of vertices not yet processed.
# u is always equal to src in first iteration
u = self.minKey(key, mstSet)
# Put the minimum distance vertex in
# the shortest path tree
mstSet[u] = True
# Update dist value of the adjacent vertices
# of the picked vertex only if the current
# distance is greater than new distance and
# the vertex in not in the shortest path tree
for v in range(self.V):
# graph[u][v] is non zero only for adjacent vertices of m
# mstSet[v] is false for vertices not yet included in MST
# Update the key only if graph[u][v] is smaller than
key[v]
if self.graph[u][v] > 0 and mstSet[v] == False and
key[v] > self.graph[u][v]:
key[v] = self.graph[u][v]
parent[v] = u
self.printMST(parent)
g = Graph(5)
g.graph = [ [0, 2, 0, 6, 0],
[2, 0, 3, 8, 5],
[0, 3, 0, 0, 7],
[6, 8, 0, 0, 9],
[0, 5, 7, 9, 0]]
g.primMST();
output: Edge Weight
Edge Weight
0 - 1 2
1 - 2 3
0 - 3 6
1 - 4 5
----------------------------------------------------------------Assignment 4----------------------------------------------------
----------------------------------------------------------n Queen ----------------------------------------------------------
N queen problem
""" Python3 program to solve N Queen Problem
using Branch or Bound """
N=8
""" A utility function to print solution """
def printSolution(board):
for i in range(N):
for j in range(N):
print(board[i][j], end = " ") print()
""" A Optimized function to check if
a queen can be placed on board[row][col] """
def isSafe(row, col, slashCode, backslashCode,
rowLookup, slashCodeLookup,
backslashCodeLookup): if
(slashCodeLookup[slashCode[row][col]]
or backslashCodeLookup[backslashCode[row][col]]
or rowLookup[row]):
return False
return True
""" A recursive utility function
to solve N Queen problem """
def solveNQueensUtil(board, col, slashCode, backslashCode,
rowLookup, slashCodeLookup,
backslashCodeLookup):
""" base case: If all queens are
placed then return True """
if(col >= N):
return True
for i in range(N):
if(isSafe(i, col, slashCode, backslashCode,
rowLookup, slashCodeLookup,
backslashCodeLookup)):
""" Place this queen in board[i][col] """
board[i][col] = 1
rowLookup[i] = True
slashCodeLookup[slashCode[i][col]] = True
backslashCodeLookup[backslashCode[i][col]] = True
""" recur to place rest of the queens """
if(solveNQueensUtil(board, col + 1,
slashCode, backslashCode, rowLookup,
slashCodeLookup, backslashCodeLookup)): return True
""" If placing queen in board[i][col]
doesn't lead to a solution,then backtrack """
""" Remove queen from board[i][col] """ board[i][col] = 0
rowLookup[i] = False
slashCodeLookup[slashCode[i][col]] =
False backslashCodeLookup[backslashCode[i][col]] = False
""" If queen can not be place in any row in
this column col then return False """
return False
""" This function solves the N Queen problem using
Branch or Bound. It mainly uses solveNQueensUtil()to
solve the problem. It returns False if queens
cannot be placed,otherwise return True or
prints placement of queens in the form of 1s.
Please note that there may be more than one
solutions,this function prints one of the
feasible solutions."""
def solveNQueens():
board = [[0 for i in range(N)]
for j in range(N)]
# helper matrices
slashCode = [[0 for i in range(N)]
for j in range(N)]
backslashCode = [[0 for i in range(N)]
for j in range(N)]
# arrays to tell us which rows are occupied
rowLookup = [False] * N
# keep two arrays to tell us
# which diagonals are occupied
x=2*N-1
slashCodeLookup = [False] * x
backslashCodeLookup = [False] * x
# initialize helper matrices
for rr in range(N):
for cc in range(N):
slashCode[rr][cc] = rr + cc
backslashCode[rr][cc] = rr - cc + 7
if(solveNQueensUtil(board, 0, slashCode, backslashCode, rowLookup,
slashCodeLookup, backslashCodeLookup) == False): print("Solution
does not exist")
return False
# solution found
printSolution(board)
return True
# Driver Cde
solveNQueens()
output
10000000
00000010
00001000
00000001
01000000
00010000
00000100
00100000
-------------------------------------------------Assignment -5 ----------------------------------------------------------------
-------------------------------------------------Chatbot------------------------------------------------------------------------
def greet(bot_name, birth_year):
print("Hello! My name is {0}.".format(bot_name))
print("I was created in {0}.".format(birth_year))
def remind_name():
print('Please, remind me your name.')
name = input()
print("What a great name you have, {0}!".format(name))
def guess_age():
print('Let me guess your age.')
print('Enter remainders of dividing your age by 3, 5 and 7.')
rem3 = int(input())
rem5 = int(input())
rem7 = int(input())
age = (rem3 * 70 + rem5 * 21 + rem7 * 15) % 105
print("Your age is {0}; that's a good time to start
programming!".format(age))
def count():
print('Now I will prove to you that I can count to any number you want.')
num = int(input())
counter = 0
while counter <= num:
print("{0} !".format(counter))
counter += 1
def test():
print("Let's test your programming knowledge.")
print("Why do we use methods?")
print("1. To repeat a statement multiple times.")
print("2. To decompose a program into several small subroutines.")
print("3. To determine the execution time of a program.")
print("4. To interrupt the execution of a program.")
answer = 2
guess = int(input())
while guess != answer:
print("Please, try again.")
guess = int(input())
print('Completed, have a nice day!')
print('.................................')
print('.................................')
print('.................................')
def end():
print('Congratulations, have a nice day!')
print('.................................')
print('.................................')
print('.................................')
input()
greet('Sbot', '2021') # change it as you need
remind_name()
guess_age()
count()
test()
end()
OutputHello! My name is Sbot.
I was created in 2021.
Please, remind me your name.
omkar
What a great name you have, omkar!
Let me guess your age.
Enter remainders of dividing your age by 3, 5 and 7.
Your age is 21; that's a good time to start programming!
Now I will prove to you that I can count to any number you want.
0!
1!
2!
3!
4!
5!
Let's test your programming knowledge.
Why do we use methods?
1. To repeat a statement multiple times.
2. To decompose a program into several small subroutines.
3. To determine the execution time of a program.
4. To interrupt the execution of a program.
Please, try again.
Completed, have a nice day!
.................................
.................................
.................................
Congratulations, have a nice day!
.................................
.................................
.................................: