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

AI Outputs (4,5,6,7)

Uploaded by

avnimote121
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)
43 views16 pages

AI Outputs (4,5,6,7)

Uploaded by

avnimote121
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/ 16

Experiment NO: 04

from collections import deque

class PuzzleState:
def __init__(self, board, parent=None, action=None):
self.board = board
self.parent = parent
self.action = action
self.blank_position = self.find_blank_position()

def __eq__(self, other):


return self.board == other.board

def __hash__(self):
return hash(str(self.board))

def find_blank_position(self):
for i in range(3):
for j in range(3):
if self.board[i][j] == 0:
return (i, j)

def get_possible_moves(self):
moves = []
x, y = self.blank_position
if x > 0:
moves.append('up')
if x < 2:
moves.append('down')
if y > 0:
moves.append('left')
if y < 2:
moves.append('right')
return moves
def move(self, direction):
x, y = self.blank_position
if direction == 'up':
new_x, new_y = x - 1, y
elif direction == 'down':
new_x, new_y = x + 1, y
elif direction == 'left':
new_x, new_y = x, y - 1
elif direction == 'right':
new_x, new_y = x, y + 1
else:
return None

new_board = [list(row) for row in self.board]


new_board[x][y], new_board[new_x][new_y] = new_board[new_x][new_y],
new_board[x][y]

return PuzzleState(new_board, self, direction)

def is_goal_state(self, goal_state):


return self.board == goal_state.board

def bfs(initial_state, goal_state):


visited = set()
queue = deque([initial_state])
while queue:
current_state = queue.popleft()

if current_state.is_goal_state(goal_state):
return get_solution_path(current_state)

visited.add(current_state)
possible_moves = current_state.get_possible_moves()

for move in possible_moves:


new_state = current_state.move(move)

if new_state not in visited:


queue.append(new_state)

return None

def get_solution_path(final_state):
path = []
current_state = final_state
while current_state.parent is not None:
path.insert(0, current_state.action)
current_state = current_state.parent
return path

def print_puzzle_board(board):
for row in board:
print(" ".join(map(str, row)))
if __name__ == "__main__":
initial_board = [
[1, 2, 3],
[0, 4, 6],
[7, 5, 8]
]

goal_board = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 0]
]

initial_state = PuzzleState(initial_board)
goal_state = PuzzleState(goal_board)

solution = bfs(initial_state, goal_state)

if solution:
print("Solution steps:")
print_puzzle_board(initial_state.board) # Print the initial state
for step in solution:
print(f"Move {step}:")
initial_state = initial_state.move(step)
print_puzzle_board(initial_state.board)
print("Number of steps:", len(solution))
else:
print("No solution found.")
Output:
Solution steps:
123
046
758
Move right:
123
406
758
Move down:
123
456
708
Move right:
123
456
780
Number of steps: 3
Experiment No : 05
import heapq

# Define the initial and goal states


initial_state = [[1, 2, 3], [4, 0, 5], [7, 8, 6]]
goal_state = [[1, 2, 3], [4, 5, 6], [7, 8, 0]]

# Define the actions to move the empty tile


actions = [(0, 1), (0, -1), (1, 0), (-1, 0)]

# Function to calculate the Manhattan distance heuristic


def manhattan_distance(state):
distance = 0
for i in range(3):
for j in range(3):
if state[i][j] != 0:
target_row, target_col = divmod(state[i][j] - 1, 3)
distance += abs(i - target_row) + abs(j - target_col)
return distance

# Function to perform A* Search


def a_star(initial_state, goal_state):
# Define PuzzleState class
class PuzzleState:
def __init__(self, state, g=0):
self.state = state
self.g = g
self.h = manhattan_distance(state)
self.f = self.g + self.h

def __lt__(self, other):


return self.f < other.f

# Initialize the priority queue


open_set = [PuzzleState(initial_state)]
heapq.heapify(open_set)

# Initialize the closed set


closed_set = set()

# Perform A* Search
while open_set:
current_state = heapq.heappop(open_set)

# Check if the current state is the goal state


if current_state.state == goal_state:
return current_state.state

# Print the current state as a 3x3 matrix


print("Intermediate State:")
for row in current_state.state:
print(row)
print()

closed_set.add(tuple(map(tuple, current_state.state)))

for action in actions:


i, j = None, None
for row in current_state.state:
if 0 in row:
i = current_state.state.index(row)
j = row.index(0)
break

ni, nj = i + action[0], j + action[1]

if 0 <= ni < 3 and 0 <= nj < 3:


new_state = [list(row) for row in current_state.state]
new_state[i][j], new_state[ni][nj] = new_state[ni][nj], new_state[i][j]

if tuple(map(tuple, new_state)) not in closed_set:


heapq.heappush(open_set, PuzzleState(new_state, current_state.g
+ 1))

# No path found
return None

# Function to print the state as a 3x3 matrix


def print_state(state):
for row in state:
print(row)
print()

# Print the initial state


print("Initial State:")
print_state(initial_state)

# Solve the 8 puzzle problem using A* Search


solution = a_star(initial_state, goal_state)

# Print the goal state


print("Goal State:")
print_state(goal_state)

# Print the solution


if solution:
print("Solution found!")
else:
print("No solution found.")
Output:
Initial State:
[1, 2, 3]
[4, 0, 5]
[7, 8, 6]

Intermediate State:
[1, 2, 3]
[4, 0, 5]
[7, 8, 6]

Intermediate State:
[1, 2, 3]
[4, 5, 0]
[7, 8, 6]

Goal State:
[1, 2, 3]
[4, 5, 6]
[7, 8, 0]

Solution found!
Experiment NO: 06
# Define the game state and the initial state
initial_state = [1, 4, 2, 6, -3, -5, 0, 7]

# Define the players


players = ['MAX', 'MIN']

# Define the utility function (a simple sum of the elements for the MAX player)
def utility(state, player):
if player == 'MAX':
return sum(state)
elif player == 'MIN':
return -sum(state)

# Define the actions (possible moves)


def actions(state):
return [i for i, val in enumerate(state) if val != 0]
# Define the Minimax algorithm
def minimax(state, depth, player):
if depth == 0 or len(actions(state)) == 0:
return utility(state, 'MAX')
if player == 'MAX':
max_eval = float('-inf')
for action in actions(state):
new_state = state.copy()
new_state[action] = state[action]
eval = minimax(new_state, depth - 1, 'MIN')
max_eval = max(max_eval, eval)
return max_eval
if player == 'MIN':
min_eval = float('inf')
for action in actions(state):
new_state = state.copy()
new_state[action] = state[action]
eval = minimax(new_state, depth - 1, 'MAX')
min_eval = min(min_eval, eval)
return min_eval
# Find the best move for the MAX player
best_move = None
best_value = float('-inf')
for action in actions(initial_state):
new_state = initial_state.copy()
new_state[action] = initial_state[action]
value = minimax(new_state, depth=3, player='MIN')
if value > best_value:
best_value = value
best_move = action
print("Best move for MAX player:", best_move)
print("Utility value of the best move:", best_value)
Output:
Best move for MAX player: 0
Utility value of the best move: 12
Experiment NO: 07
import random

# Define the initial state and the goal state for the 8-puzzle
initial_state = [2, 8, 3, 1, 6, 4, 7, 0, 5]
goal_state = [1, 2, 3, 8, 0, 4, 7, 6, 5]

# Define the size of the population and the number of generations


population_size = 100
num_generations = 1000

# Define the mutation rate (probability of mutation)


mutation_rate = 0.2

def fitness(state):
# Calculate the fitness of a state (number of misplaced tiles)
return sum(1 for i in range(9) if state[i] != goal_state[i])

def crossover(parent1, parent2):


# Perform one-point crossover to create a child
crossover_point = random.randint(1, 7)
child = parent1[:crossover_point] + parent2[crossover_point:]
return child

def mutate(state):
# Apply mutation by swapping two random tiles
i, j = random.sample(range(9), 2)
state[i], state[j] = state[j], state[i]

def genetic_algorithm():
# Initialize the population with random states
population = [random.sample(range(9), 9) for _ in range(population_size)]

for generation in range(num_generations):


# Calculate fitness for each state in the population
fitness_scores = [(state, fitness(state)) for state in population]

# Sort the population by fitness


fitness_scores.sort(key=lambda x: x[1])

# Print the best solution candidate at this generation


best_solution = fitness_scores[0][0]
print(f"Generation {generation}: Best Solution - {best_solution}, Fitness -
{fitness_scores[0][1]}")

# Check if we have reached the goal state


if fitness_scores[0][1] == 0:
print("Solution found!")
print("Solution:", best_solution)
return

# Select the top 20% of the population as parents for reproduction


num_parents = int(0.2 * population_size)
parents = [state for state, _ in fitness_scores[:num_parents]]

# Create a new population through crossover and mutation


new_population = parents.copy()
while len(new_population) < population_size:
parent1, parent2 = random.choices(parents, k=2)
child = crossover(parent1, parent2)
if random.random() < mutation_rate:
mutate(child)
new_population.append(child)

# Update the population


population = new_population

print("No solution found after", num_generations, "generations.")

if __name__ == "__main__":
genetic_algorithm()
Output:
Generation 0: Best Solution - [1, 7, 0, 8, 2, 4, 3, 6, 5], Fitness - 4
Generation 1: Best Solution - [1, 7, 0, 8, 2, 4, 3, 6, 5], Fitness - 4
Generation 2: Best Solution - [1, 2, 2, 8, 0, 4, 2, 3, 5], Fitness - 3
Generation 3: Best Solution - [1, 2, 1, 8, 0, 4, 3, 6, 5], Fitness - 2
Generation 4: Best Solution - [1, 2, 3, 8, 0, 4, 2, 6, 5], Fitness - 1
Generation 5: Best Solution - [1, 2, 3, 8, 0, 4, 2, 6, 5], Fitness - 1
Generation 6: Best Solution - [1, 2, 3, 8, 0, 4, 2, 6, 5], Fitness - 1
Generation 7: Best Solution - [1, 2, 3, 8, 0, 4, 7, 6, 5], Fitness - 0
Solution found!
Solution: [1, 2, 3, 8, 0, 4, 7, 6, 5]
>

You might also like