0% found this document useful (0 votes)
14 views11 pages

Experiment 3

The document outlines an experiment to implement Best First Search and A* algorithms for solving the 8-Puzzle problem, which involves arranging tiles on a 3x3 board. It includes code for both algorithms, detailing the methods for calculating costs, generating new states, and finding solutions. The document also provides examples of initial and goal states, along with the expected outputs.

Uploaded by

Abhi Mishra
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)
14 views11 pages

Experiment 3

The document outlines an experiment to implement Best First Search and A* algorithms for solving the 8-Puzzle problem, which involves arranging tiles on a 3x3 board. It includes code for both algorithms, detailing the methods for calculating costs, generating new states, and finding solutions. The document also provides examples of initial and goal states, along with the expected outputs.

Uploaded by

Abhi Mishra
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/ 11

Experiment 3

Aim: Implement Best first search and least cost search for 8-Puzzle
problem

Theory:
Given a 3×3 board with 8 tiles (each numbered from 1 to 8) and one
empty space, the objective is to place the numbers to match the final
configuration using the empty space. We can slide four adjacent tiles
(left, right, above, and below) into the empty space.

Code:

import copy
from heapq import heappush, heappop

n=3
row = [1, 0, -1, 0]
col = [0, -1, 0, 1]

class priorityQueue:
def __init__(self):
self.heap = []

1
def push(self, k):
heappush(self.heap, k)

def pop(self):
return heappop(self.heap)

def empty(self):
return not self.heap

class node:
def __init__(self, parent, mat, empty_tile_pos, cost, level):
self.parent = parent
self.mat = mat
self.empty_tile_pos = empty_tile_pos
self.cost = cost
self.level = level

def __lt__(self, nxt):


return self.cost < nxt.cost

def calculateCost(mat, final):


count = 0
for i in range(n):
2
for j in range(n):
if mat[i][j] and mat[i][j] != final[i][j]:
count += 1
return count

def newNode(mat, empty_tile_pos, new_empty_tile_pos, level,


parent, final):
new_mat = copy.deepcopy(mat)
x1, y1 = empty_tile_pos
x2, y2 = new_empty_tile_pos
new_mat[x1][y1], new_mat[x2][y2] = new_mat[x2][y2],
new_mat[x1][y1]
cost = calculateCost(new_mat, final)
return node(parent, new_mat, new_empty_tile_pos, cost, level)

def printMatrix(mat):
for i in range(n):
for j in range(n):
print("%d " % (mat[i][j]), end=" ")
print()

def isSafe(x, y):


return 0 <= x < n and 0 <= y < n

3
def printPath(root):
if root is None:
return
printPath(root.parent)
printMatrix(root.mat)
print()

def solve(initial, empty_tile_pos, final):


pq = priorityQueue()
cost = calculateCost(initial, final)
root = node(None, initial, empty_tile_pos, cost, 0)
pq.push(root)
while not pq.empty():
minimum = pq.pop()
if minimum.cost == 0:
printPath(minimum)
return
for i in range(4):
new_tile_pos = [
minimum.empty_tile_pos[0] + row[i],
minimum.empty_tile_pos[1] + col[i],
]
4
if isSafe(new_tile_pos[0], new_tile_pos[1]):
child = newNode(
minimum.mat,
minimum.empty_tile_pos,
new_tile_pos,
minimum.level + 1,
minimum,
final,
)
pq.push(child)

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


final = [[1, 2, 3], [5, 8, 6], [0, 7, 4]]
empty_tile_pos = [1, 2]
solve(initial, empty_tile_pos, final)

5
Output:

6
Aim: Implement the steps of A* Algorithms for 8-Puzzle problem.

Theory:
The A* (A-Star) algorithm is a popular pathfinding and graph traversal
algorithm that is widely used in AI to find the shortest path from a
start state to a goal state. It is particularly useful for solving problems
like the 8-puzzle.

Code:
import heapq
import copy

# Corrected Manhattan distance to handle goal as a 2D array


def manhattan_distance(state, goal):
distance = 0
for i in range(3):
for j in range(3):
value = state[i][j]
if value != 0:
for x in range(3):
for y in range(3):
if goal[x][y] == value:
distance += abs(i - x) + abs(j - y)
break

7
return distance

def is_goal(state, goal):


return state == goal

def get_neighbors(state):
neighbors = []
x, y = next((i, j) for i in range(3) for j in range(3) if state[i][j] == 0)
moves = [(-1, 0), (1, 0), (0, -1), (0, 1)]
for dx, dy in moves:
nx, ny = x + dx, y + dy
if 0 <= nx < 3 and 0 <= ny < 3:
new_state = copy.deepcopy(state)
new_state[x][y], new_state[nx][ny] = new_state[nx][ny],
new_state[x][y]
neighbors.append(new_state)
return neighbors

def a_star_search(start, goal):


visited = set()
pq = []
heapq.heappush(pq, (manhattan_distance(start, goal), 0, start, []))
while pq:

8
f, g, current, path = heapq.heappop(pq)
if is_goal(current, goal):
return path + [current]
visited.add(tuple(map(tuple, current)))
for neighbor in get_neighbors(current):
if tuple(map(tuple, neighbor)) not in visited:
heapq.heappush(
pq,
(
g + 1 + manhattan_distance(neighbor, goal),
g + 1,
neighbor,
path + [current],
),
)
return None

# Test with the provided start and goal states


start_state = [[1, 2, 3], [4, 0, 5], [7, 8, 6]]
goal_state = [[1, 2, 3], [4, 5, 6], [7, 8, 0]]
solution = a_star_search(start_state, goal_state)

# Display the output


9
if solution:
for step in solution:
for row in step:
print(row)
print("------")
else:
print("No solution found.")

Output:
Initial State:

Step:1

Final Stage:

10
11

You might also like