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")