AI Practical Exam
AI Practical Exam
Depth first search: In DFS, we start with a node and start exploring it’s connected
nodes keeping on suspending the exploration of previous nodes.
Program:
def dfs(graph, start):
visited = set()
stack = [start]
while stack:
node = stack.pop()
if node not in visited:
visited.add(node)
print(node, end=' ')
stack.extend(neighbor for neighbor in graph[node] if neighbor not in visited)
return visited
graph = {
'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F'],
'D': [],
'E': ['F'],
'F': [] }
dfs(graph, 'B')
Output:
2) Write a program to simulate 4-Queen / N-Queen problem.
4-Queen problem : The 4-Queen problem is a special case of the N-Queen problem, a
classic puzzle in combinatorial mathematics and computer science. The objective is to
place 4 queens on a 4x4 chessboard in such a way that no two queens threaten each
other.
Program:
def is_safe(board, row, col, N):
for i in range(col):
if board[row][i] == 'Q':
return False
for i, j in zip(range(row, -1, -1), range(col, -1, -1)):
if board[i][j] == 'Q':
return False
for i, j in zip(range(row, N, 1), range(col, -1, -1)):
if board[i][j] == 'Q':
return False
return True
def solve_nqueens_util(board, col, N, solutions):
if col >= N:
solutions.append(["".join(row) for row in board])
return
for i in range(N):
if is_safe(board, i, col, N):
# Place this queen in board[i][col]
board[i][col] = 'Q'
solve_nqueens_util(board, col + 1, N, solutions)
board[i][col] = '.'
def solve_nqueens(N):
board = [['.' for _ in range(N)] for _ in range(N)]
solutions = []
solve_nqueens_util(board, 0, N, solutions)
if not solutions:
print("Solution does not exist")
else:
for solution in solutions:
print_board(solution)
return len(solutions)
def print_board(board):
for row in board:
print(" ".join(row))
print()
N=4
number_of_solutions = solve_nqueens(N)
print(f"Number of solutions: {number_of_solutions}")
Output:
3) Write a program to implement breadth first search algorithm.
Breadth first search: Breadth-First Search (BFS) is a fundamental algorithm
in computer science used to explore or traverse a graph or tree. It
systematically visits nodes in a level-by-level order, starting from a given
node (often called the root in trees or the source in graphs) and exploring all
neighboring nodes at the present depth before moving on to nodes at the
next depth level.
Program:
from collections import deque
def bfs(graph, start):
visited = set()
queue = deque([start])
while queue:
node = queue.popleft()
if node not in visited:
visited.add(node)
print(node, end=' ')
queue.extend(neighbor for neighbor in graph[node] if neighbor not in visited)
return visited
graph = {
'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F'],
'D': [],
'E': ['F'],
'F': []
}
bfs(graph, 'A')
Output:
4) Write a program to solve water jug problem
def print_state(step, p, q):
def water_jug_problem():
# Initialize state
step = 1
# Fill Jug A
p=4
print_state(step, p, q)
step += 1
# Fill Jug B
q=3
print_state(step, p, q)
step += 1
# Empty Jug A
p=0
print_state(step, p, q)
step += 1
# Empty Jug B
q=0
print_state(step, p, q)
step += 1
# Transfer complete water from Jug B to Jug A
q = 0 # Jug B is empty
print_state(step, p, q)
step += 1
p = 0 # Jug A is empty
print_state(step, p, q)
step += 1
p = 4 # Jug A is full
print_state(step, p, q)
step += 1
print_state(step, p, q)
step += 1
if __name__ == "__main__":
water_jug_problem()
5) Write a program to Solve tower of Hanoi problem.
Tower of Hanoi: The Tower of Hanoi is a classic puzzle involving three rods
and a set of disks of different sizes. The objective is to move all the disks
from the source rod to the destination rod, using the third rod as an
auxiliary, while adhering to the rules: only one disk can be moved at a time,
and no disk may be placed on top of a smaller disk. The problem
demonstrates recursive problem-solving and has a well-known solution with
a minimum number of moves.
Program:
# Driver code
N=2
# A, C, B are the name of rods
TowerOfHanoi(N, 'A', 'C', 'B')
Output:
6) Write a program to Implement alpha beta search.
Alpha beta search: Alpha-beta search is an optimization technique for the minimax
algorithm used in game theory and artificial intelligence to make decisions in two-
player games. It helps reduce the number of nodes evaluated in the search tree by
pruning branches that cannot possibly influence the final decision.
Program:
def alpha_beta_search(node, depth, alpha, beta, maximizing_player):
if depth == 0 or is_terminal(node):
return evaluate(node)
if maximizing_player:
value = float('-inf')
for child in get_children(node):
value = max(value, alpha_beta_search(child, depth - 1, alpha, beta, False))
alpha = max(alpha, value)
if beta <= alpha:
break
return value
else:
value = float('inf')
for child in get_children(node):
value = min(value, alpha_beta_search(child, depth - 1, alpha, beta, True))
beta = min(beta, value)
if beta <= alpha:
break
return value
def is_terminal(node):
return isinstance(node, int)
def evaluate(node):
return node
def get_children(node):
return [node - 1, node - 2] if isinstance(node, int) and node > 0 else []
# Example usage:
initial_node = 10
alpha = float('-inf')
beta = float('inf')
depth = 4
best_value = alpha_beta_search(initial_node, depth, alpha, beta, True)
print("Best value:", best_value)
Output:
7) Simulate tic – tac – toe game using min-max algorithm.
Program:
import math
# Define constants
EMPTY = 0
PLAYER_X = 1
PLAYER_O = 2
def print_board(board):
symbols = {EMPTY: '.', PLAYER_X: 'X', PLAYER_O: 'O'}
for row in board:
print(' '.join(symbols[cell] for cell in row))
print()
def check_winner(board):
# Check rows, columns, and diagonals
lines = [board[0], board[1], board[2],
[board[0][0], board[1][0], board[2][0]],
[board[0][1], board[1][1], board[2][1]],
[board[0][2], board[1][2], board[2][2]],
[board[0][0], board[1][1], board[2][2]],
[board[2][0], board[1][1], board[0][2]]]
def is_board_full(board):
return all(cell != EMPTY for row in board for cell in row)
if is_maximizing:
best_score = -math.inf
for i in range(3):
for j in range(3):
if board[i][j] == EMPTY:
board[i][j] = PLAYER_X
score = minimax(board, depth + 1, False)
board[i][j] = EMPTY
best_score = max(score, best_score)
return best_score
else:
best_score = math.inf
for i in range(3):
for j in range(3):
if board[i][j] == EMPTY:
board[i][j] = PLAYER_O
score = minimax(board, depth + 1, True)
board[i][j] = EMPTY
best_score = min(score, best_score)
return best_score
def find_best_move(board):
best_move = None
best_score = -math.inf
for i in range(3):
for j in range(3):
if board[i][j] == EMPTY:
board[i][j] = PLAYER_X
move_score = minimax(board, 0, False)
board[i][j] = EMPTY
if move_score > best_score:
best_score = move_score
best_move = (i, j)
return best_move
def play_game():
board = [[EMPTY] * 3 for _ in range(3)]
current_player = PLAYER_X
while True:
print_board(board)
if current_player == PLAYER_X:
print("Player X's turn:")
move = find_best_move(board)
else:
print("Player O's turn:")
move = find_best_move(board) # This can be replaced with human input for Player O
if move is None:
print("No more moves. It's a tie!")
break
i, j = move
board[i][j] = current_player
winner = check_winner(board)
if winner:
print_board(board)
print(f"Player {'X' if winner == PLAYER_X else 'O'} wins!")
break
if is_board_full(board):
print_board(board)
print("It's a tie!")
break
if __name__ == "__main__":
play_game()
8) Write a program for shuffle deck of cards
# importing modules
import itertools, random
# make a deck of cards
deck = list(itertools.product(range(1,14),['Spade','Heart','Diamond','Club']))
# shuffle the cards
random.shuffle(deck)
# draw five cards
print("You got:")
for i in range(3):
print(deck[i][0], "of", deck[i][1])
Q9)
Q10)