0% found this document useful (0 votes)
27 views16 pages

BFS

AI algorithms

Uploaded by

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

BFS

AI algorithms

Uploaded by

madmax25u
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

BFS

from collections import deque

def BFS(graph, start):


visited = set()
queue = deque([start])
bfs_order = []

while queue:
vertex = queue.popleft()
if vertex not in visited:
visited.add(vertex)
bfs_order.append(vertex)
queue.extend(neighbor for neighbor in graph[vertex] if neighbor not in visited)

return bfs_order
graph = {
0: [1, 2],
1: [0, 3, 4],
2: [0, 5],
3: [1],
4: [1],
5: [2]
}
start_vertex = 0
result = BFS(graph, start_vertex)
print(result)

DFS

def DFS(graph, start):


visited = set()
result = []

def dfs_recursive(vertex):
visited.add(vertex)
result.append(vertex)
for neighbor in graph[vertex]:
if neighbor not in visited:
dfs_recursive(neighbor)
dfs_recursive(start)
return result

graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B'],
'F': ['C']
}
print(DFS(graph, 'A'))

Missionary
from collections import deque
def is_valid(state):
m_left, c_left, m_right, c_right, boat = state
return (m_left == 0 or m_left >= c_left) and (m_right == 0 or m_right >= c_right)
def bfs(start):
goal = (0, 0, start[0], start[1], 0)
moves = [(1, 0), (2, 0), (0, 1), (0, 2), (1, 1)]
queue = deque([start])
visited = {start: None}
while queue:
state = queue.popleft()
if state[:4] == goal[:4]:
return build_path(state, visited)
m_left, c_left, m_right, c_right, boat = state
for m, c in moves:
if boat == 1:
new_state = (m_left - m, c_left - c, m_right + m, c_right + c, 0)
else:
new_state = (m_left + m, c_left + c, m_right - m, c_right - c, 1)
if new_state not in visited and is_valid(new_state):
visited[new_state] = state
queue.append(new_state)
return None
def build_path(state, visited):
path = []
while state:
path.append(state)
state = visited[state]
return path[::-1]
def main():
m = int(input("Enter the number of missionaries on the left bank: "))
c = int(input("Enter the number of cannibals on the left bank: "))
start = (m, c, 0, 0, 1)
solution = bfs(start)
if solution:
for step in solution:
print(step)
else:
print("No solution found.")
if __name__ == "__main__":
main()

N Queens 

def is_safe(board, row, col):


for i in range(row):
if board[i] == col or \
board[i] - i == col - row or \
board[i] + i == col + row:
return False
return True

def solve_n_queens(n, row=0, board=[]):


if row == n:
return board
for col in range(n):
if is_safe(board, row, col):
solution = solve_n_queens(n, row + 1, board + [col])
if solution:
return solution
return None

n=8
solution = solve_n_queens(n)
if solution:
for i in range(n):
row = ['.'] * n
row[solution[i]] = 'Q'
print(" ".join(row))
else:
print("No solution exists.")

UCS
import heapq
def ucs(graph, start, goal):
queue = [(0, start, [start])]
visited = set()
while queue:
cost, node, path = heapq.heappop(queue)
if node == goal:
return cost, path
if node not in visited:
visited.add(node)
for neighbor, edge_cost in graph[node]:
heapq.heappush(queue, (cost + edge_cost, neighbor, path + [neighbor]))
return float('inf'), []
graph = {
'A': [('B', 1), ('C', 4)],
'B': [('A', 1), ('C', 2), ('D', 5)],
'C': [('A', 4), ('B', 2), ('D', 1)],
'D': [('B', 5), ('C', 1)]
}
start = 'A'
goal = 'D'
cost, path = ucs(graph, start, goal)
print(f"Cost from {start} to {goal}: {cost}")
print(f"Path: {' -> '.join(path)}")
Iterative DFS
def dfs(node, depth, goal):
if depth == 0 and node == goal:
return [node]
if depth > 0:
for neighbor in graph.get(node, []):
path = dfs(neighbor, depth - 1, goal)
if path:
return [node] + path
return None
def ids(start, goal):
depth = 0
while True:
path = dfs(start, depth, goal)
if path:
return path
depth += 1
graph = {
'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F'],
'D': [],
'E': [],
'F': []
}
start = 'A'
goal = 'E'
path = ids(start, goal)
print(f"Path from {start} to {goal}: {' -> '.join(path)}")

Depth DFS

def dls(node, depth, goal):


if depth == 0:
return [node] if node == goal else None
if depth > 0:
for neighbor in graph.get(node, []):
path = dls(neighbor, depth - 1, goal)
if path:
return [node] + path
return None
graph = {
'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F'],
'D': [],
'E': [],
'F': []
}
start = 'A'
goal = 'E'
depth_limit = 2
path = dls(start, depth_limit, goal)
print(f"Path from {start} to {goal} with depth limit {depth_limit}: {' -> '.join(path) if path
else 'Not found'}")

Bidirectional 
from collections import deque
def bidirectional_search(graph, start, goal):
start_frontier = deque([start])
goal_frontier = deque([goal])
start_visited = {start: None}
goal_visited = {goal: None}
while start_frontier and goal_frontier:
if start_frontier:
node = start_frontier.popleft()
if node in goal_visited:
return construct_path(start_visited, goal_visited, node)
for neighbor in graph[node]:
if neighbor not in start_visited:
start_visited[neighbor] = node
start_frontier.append(neighbor)
if goal_frontier:
node = goal_frontier.popleft()
if node in start_visited:
return construct_path(start_visited, goal_visited, node)
for neighbor in graph[node]:
if neighbor not in goal_visited:
goal_visited[neighbor] = node
goal_frontier.append(neighbor)
return None
def construct_path(start_visited, goal_visited, meeting_point):
path = []
node = meeting_point
while node is not None:
path.append(node)
node = start_visited[node]
path.reverse()
node = goal_visited[meeting_point]
while node is not None:
path.append(node)
node = goal_visited[node]
return path
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E', 'G'],
'G': ['F']
}
start = 'A'
goal = 'G'
path = bidirectional_search(graph, start, goal)
print(f"Path: {path}")
Greedy bfs
import heapq
def greedy_best_first_search(graph, start, goal, heuristic):
frontier = [(heuristic[start], start)]
came_from = {start: None}
visited = set()
while frontier:
_, current = heapq.heappop(frontier)
if current == goal:
return reconstruct_path(came_from, start, goal)
visited.add(current)
for neighbor in graph[current]:
if neighbor not in visited:
came_from[neighbor] = current
heapq.heappush(frontier, (heuristic[neighbor], neighbor))
return None
def reconstruct_path(came_from, start, goal):
path = []
node = goal
while node is not None:
path.append(node)
node = came_from[node]
path.reverse()
return path
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E', 'G'],
'G': ['F']
}
heuristic = {
'A': 7,
'B': 6,
'C': 2,
'D': 3,
'E': 4,
'F': 1,
'G': 0
}
start = 'A'
goal = 'G'
path = greedy_best_first_search(graph, start, goal, heuristic)
print(f"Path: {path}")

A star
import heapq
def a_star(graph, start, goal, heuristic, cost):
frontier=[(0+heuristic[start], start)]
g_cost={start: 0}
came_from={start: None}
while frontier:
_, current=heapq.heappop(frontier)
if current==goal:
return reconstruct_path(came_from, start, goal)
for neighbor, move_cost in graph[current]:
new_cost=g_cost[current] + move_cost
if neighbor not in g_cost or new_cost < g_cost[neighbor]:
g_cost[neighbor]=new_cost
priority=new_cost+heuristic[neighbor]
heapq.heappush(frontier, (priority, neighbor))
came_from[neighbor]=current
return None
def reconstruct_path(came_from, start, goal):
path,node=[],goal
while node:
path.append(node)
node=came_from[node]
return path[::-1]
graph={'A': [('B',1),('C',3)],'B': [('A',1),('D',1),('E',5)],'C': [('A',3),('F',2)],
'D': [('B',1)],'E': [('B',5),('F',2)],'F': [('C',2),('E',2),('G',1)],'G': [('F',1)]}
heuristic={'A':7,'B':6,'C':2,'D':3,'E':4,'F':1,'G':0}
print(a_star(graph,'A','G',heuristic,graph))
TSP
import heapq

def a_star_tsp(graph, start):


frontier = [(0, start, [start], 0)]
n = len(graph)
while frontier:
_, current, path, cost = heapq.heappop(frontier)
if len(path) == n and path[0] == start:
return path, cost
for neighbor, move_cost in graph[current]:
if neighbor not in path:
new_cost = cost + move_cost
priority = new_cost + heuristic(neighbor, graph)
heapq.heappush(frontier, (priority, neighbor, path + [neighbor], new_cost))
return None
def heuristic(node, graph):
return min([cost for _, cost in graph[node]])
graph = {
0: [(1, 10), (2, 15), (3, 20)],
1: [(0, 10), (2, 35), (3, 25)],
2: [(0, 15), (1, 35), (3, 30)],
3: [(0, 20), (1, 25), (2, 30)]
}
start_node = 0
tour, cost = a_star_tsp(graph, start_node)
print(f"Optimal TSP tour: {tour} with total cost: {cost}")

Minmax
import math
PLAYER_X = 'X'
PLAYER_O = 'O'
EMPTY = ' '

def print_board(board):
for row in board:
print('|'.join(row))
print('-' * 5)

def check_winner(board):
for row in board:
if row[0] == row[1] == row[2] != EMPTY:
return row[0]
for col in range(3):
if board[0][col] == board[1][col] == board[2][col] != EMPTY:
return board[0][col]
if board[0][0] == board[1][1] == board[2][2] != EMPTY:
return board[0][0]
if board[0][2] == board[1][1] == board[2][0] != EMPTY:
return board[0][2]
return None

def is_full(board):
return all(cell != EMPTY for row in board for cell in row)

def alpha_beta(board, depth, alpha, beta, is_maximizing):


winner = check_winner(board)
if winner == PLAYER_X:
return 10 - depth
elif winner == PLAYER_O:
return depth - 10
elif is_full(board):
return 0

if is_maximizing:
max_eval = -math.inf
for row in range(3):
for col in range(3):
if board[row][col] == EMPTY:
board[row][col] = PLAYER_X
eval = alpha_beta(board, depth + 1, alpha, beta, False)
board[row][col] = EMPTY
max_eval = max(max_eval, eval)
alpha = max(alpha, eval)
if beta <= alpha:
break
return max_eval
else:
min_eval = math.inf
for row in range(3):
for col in range(3):
if board[row][col] == EMPTY:
board[row][col] = PLAYER_O
eval = alpha_beta(board, depth + 1, alpha, beta, True)
board[row][col] = EMPTY
min_eval = min(min_eval, eval)
beta = min(beta, eval)
if beta <= alpha:
break
return min_eval

def best_move(board):
best_score = -math.inf
move = (-1, -1)
alpha = -math.inf
beta = math.inf

for row in range(3):


for col in range(3):
if board[row][col] == EMPTY:
board[row][col] = PLAYER_X
score = alpha_beta(board, 0, alpha, beta, False)
board[row][col] = EMPTY
if score > best_score:
best_score = score
move = (row, col)
return move
def main():
board = [[EMPTY, EMPTY, EMPTY] for _ in range(3)]

while True:
print_board(board)
if is_full(board):
print("It's a draw!")
break
move = best_move(board)
if move != (-1, -1):
board[move[0]][move[1]] = PLAYER_X
if check_winner(board):
print_board(board)
print("Player X wins!")
break
if is_full(board):
print("It's a draw!")
break
print("Player O's turn. Enter your move (row and column):")
row, col = map(int, input().split())
if board[row][col] == EMPTY:
board[row][col] = PLAYER_O
else:
print("Invalid move. Try again.")
continue
if check_winner(board):
print_board(board)
print("Player O wins!")
break

if __name__ == "__main__":
main()
Aplha
import math

def evaluate(board):
for row in board:
if row.count('X') == 3:
return 10
if row.count('O') == 3:
return -10
for col in range(3):
if all(board[row][col] == 'X' for row in range(3)):
return 10
if all(board[row][col] == 'O' for row in range(3)):
return -10
if all(board[i][i] == 'X' for i in range(3)):
return 10
if all(board[i][2 - i] == 'O' for i in range(3)):
return -10
return 0

def is_board_full(board):
return all(cell in ['X', 'O'] for row in board for cell in row)

def alpha_beta(board, depth, alpha, beta, is_maximizing):


score = evaluate(board)
if score == 10 or score == -10:
return score - depth if is_maximizing else score + depth
if is_board_full(board):
return 0

if is_maximizing:
max_eval = -math.inf
for row in range(3):
for col in range(3):
if board[row][col] == '':
board[row][col] = 'X'
eval = alpha_beta(board, depth + 1, alpha, beta, False)
board[row][col] = ''
max_eval = max(max_eval, eval)
alpha = max(alpha, eval)
if beta <= alpha:
break
return max_eval
else:
min_eval = math.inf
for row in range(3):
for col in range(3):
if board[row][col] == '':
board[row][col] = 'O'
eval = alpha_beta(board, depth + 1, alpha, beta, True)
board[row][col] = ''
min_eval = min(min_eval, eval)
beta = min(beta, eval)
if beta <= alpha:
break
return min_eval

def best_move(board):
best_score = -math.inf
move = (-1, -1)
for row in range(3):
for col in range(3):
if board[row][col] == '':
board[row][col] = 'X'
score = alpha_beta(board, 0, -math.inf, math.inf, False)
board[row][col] = ''
if score > best_score:
best_score = score
move = (row, col)
return move

board1 = [
['X', 'O', 'X'],
['X', 'O', ''],
['', '', 'O']
]

board2 = [
['X', 'X', 'O'],
['X', '', 'O'],
['', 'O', '']
]

board3 = [
['X', 'O', 'X'],
['X', 'X', 'O'],
['O', 'X', 'O']
]

for idx, board in enumerate([board1, board2, board3], start=1):


move = best_move(board)
print(f"Board {idx}:\n{board}\nThe best move for X is: {move}\n")

You might also like