You are on page 1of 5

EXERCISE - 04

PROBLEM STATEMENT:
Design and implement solution for 8-puzzle problem using Greedy Best First Search.
AIM: To Design and implement solution for 8-puzzle problem using Greedy Best
First Search.
Description:
8-puzzle problem: An 8 puzzle is a simple game consisting of a 3 x 3 grid/matrix
(containing 9 squares). One of the squares is empty. The object is to move squares
around into different positions and have the numbers displayed in the "goal state".

INITIAL STATE GOAL STATE


123 123
046 => 456
758 780
Greedy Best First Search:
Greedy best-first search is an informed search algorithm where the evaluation
function is strictly equal to the heuristic function, disregarding the edge weights in a
weighted graph because only the heuristic value is considered.

Greedy Best First Search (GBFS) is a heuristic search algorithm that uses a heuristic
function to evaluate nodes in the search space and selects the node that appears to be
the most promising. In the case of the 8-puzzle, a common heuristic is the Manhattan
distance, which calculates the sum of the distances between each tile and its goal
position.
Process:
 Greedy Best-First Search works by evaluating the cost of each possible path and
then expanding the path with the lowest cost. This process is repeated until the
goal is reached.
 The algorithm uses a heuristic function to determine which path is the most
promising.
 The heuristic function takes into account the cost of the current path and the
estimated cost of the remaining paths.
 If the cost of the current path is lower than the estimated cost of the remaining
paths, then the current path is chosen. This process is repeated until the goal is
reached.
Program code:
import heapq

class PuzzleState:
def __init__(self, puzzle, parent=None):
self.puzzle = puzzle
self.parent = parent
self.cost = 0 # Cost from the initial state to this state
self.heuristic = self.calculate_heuristic()

def __lt__(self, other):


return (self.cost + self.heuristic) < (other.cost + other.heuristic)

def __eq__(self, other):


return self.puzzle == other.puzzle

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

def calculate_heuristic(self):
# Manhattan distance heuristic
heuristic = 0
goal_state = [[1, 2, 3], [4, 5, 6], [7, 8, 0]]
for i in range(3):
for j in range(3):
if self.puzzle[i][j] != 0:
goal_i, goal_j = divmod(self.puzzle[i][j] - 1, 3)
heuristic += abs(i - goal_i) + abs(j - goal_j)
return heuristic

def get_blank_position(puzzle):
for i in range(3):
for j in range(3):
if puzzle[i][j] == 0:
return i, j

def get_neighbors(state):
i, j = get_blank_position(state.puzzle)
neighbors = []

# Possible moves: up, down, left, right


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

for move in moves:


new_i, new_j = i + move[0], j + move[1]
if 0 <= new_i < 3 and 0 <= new_j < 3:
new_puzzle = [row[:] for row in state.puzzle]
new_puzzle[i][j], new_puzzle[new_i][new_j] = new_puzzle[new_i][new_j],
new_puzzle[i][j]
neighbors.append(PuzzleState(new_puzzle, state))

return neighbors

def greedy_best_first_search(initial_state):
priority_queue = [initial_state]
visited = set()

while priority_queue:
current_state = heapq.heappop(priority_queue)

if current_state.puzzle == [[1, 2, 3], [4, 5, 6], [7, 8, 0]]:


return get_solution_path(current_state)

visited.add(current_state)

for neighbor in get_neighbors(current_state):


if neighbor not in visited and neighbor not in priority_queue:
neighbor.parent = current_state
neighbor.cost = current_state.cost + 1
heapq.heappush(priority_queue, neighbor)

return None

def get_solution_path(final_state):
path = []
current_state = final_state
while current_state:
path.append(current_state.puzzle)
current_state = current_state.parent
return path[::-1]

def print_solution_path(path):
for step, state in enumerate(path):
print(f"Step {step}:\n")
for row in state:
print(row)
print("\n")

if __name__ == "__main__":
initial_puzzle = [[1, 2, 3], [4, 0, 5], [7, 8, 6]]
initial_state = PuzzleState(initial_puzzle)

solution_path = greedy_best_first_search(initial_state)

if solution_path:
print("Solution found!\n")
print_solution_path(solution_path)
else:
print("No solution found.")
Output:
Solution found!
Step 1: Move (1, 1) ->
[1, 2, 3]
[4, 5, 0]
[7, 8, 6]

Step 2: Move (2, 1) ->


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

Step 3: Move (2, 2) ->


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

You might also like