ITAI Report
ITAI Report
Assignment
April 4, 2024
1 Task 1: 8-Puzzle
Code structure
Class Node
Class Utils
Class Heuristics
Class PuzzleSearchStrategy
Class BFSPuzzle
Class AStarPuzzle
Class UserInteraction
Class BarChart
2 Task 2: Pacman
This class represents a state of an 8-puzzle. Each node holds information about the
current state of the puzzle and its relation to other nodes in the search process.
• Attributes:
• state: a 2D list represents the current state of the puzzle.
• id: an identifier for the node generated from the string representation of the state.
• action: the action that led to the state from its parent node.
• parent: a reference to the parent node in the search tree.
• Methods:
• str (): defines how to print a node.
• lt (): enables comparison between nodes based on their IDs.
• get successors(): generates the list of successor nodes reachable from the current
state.
• get dest pos(): calculates the new position of the tile based on the applied action.
• get blank pos(): finds the position of the blank tile.
• get id(), get node str(), get action(): get the ID, string representation of the state,
the action that led to this node from its parent, respectively.
This class provides functions for generating and validating the puzzle
configurations for the 8-puzzle problem.
• generate unique matrix(): this method generates a unique 3x3 matrix for the
8-puzzle problem.
• is puzzle solvable(): this method checks if a given 3x3 matrix represents a
solvable 8-puzzle configuration.
• generate n solvable unique matrices(): this method generates a specified
number of unique and solvable matrices for the 8-puzzle problem.
This class provides 2 heuristic functions used in our assignment to estimate the
cost of reaching the goal state from a given node.
• get misplaced num(): counts the number of tiles that are not in their correct
positions in the current node’s state compared to the goal state.
• get manhattan distance(): calculates the sum of the Manhattan distances
between each tile’s current position and its goal position.
This class defines a frame for searching solutions to the 8 puzzle problem.
• Attributes:
• self.goal1, self.goal2: store instances of the Node class representing the 2 possible
goals for the 8-puzzle.
• self.dot: used for creating visual representations of the search process.
• self.dst: holds the destination node reached during a search.
• Methods:
• get path(): returns the sequence of actions that leads from the source node to the
destination node.
• draw path(): visualizes the search path.
• graph search(): is the abstract method for the specific search algorithms (BFS and
A*).
Algorithm 1
0: expanded ← set(); frontier ← Queue()
0: frontier .push(problem.initial state)
0: while !frontier .isEmpty() do
0: node ← frontier .pop()
0: expanded.add(node.get id())
0: if problem.goal test(node) then
0: return find path(node)
0: end if
0: for successor in problem.get successor (node) do
0: if successor .get id() not in expanded then
0: frontier .push(successor , successor .path cost)
0: parents[successor .get id()] = node
0:
0:
return path
Algorithm 2
0: expanded ← set(); frontier ← PriorityQueue()
0: frontier .push(problem.initial state, 0)
0: while !frontier .isEmpty() do
0: node ← frontier .pop()
0: if problem.goal test(node) then
0: expanded.add(node.get id())
0: return find path(problem.initial state, node)
0: end if
0: expanded.add(node.get id())
0: for successor in problem.get successor (node) do
0: if successor .get id() not in expanded then
0: f score ← successor .path cost + heuristic(node, successor .state)
0: frontier .push(successor , f score)
0:
0:
return path
This class main purpose is to prompt user to input a valid state of 8 puzzle and
choose the algorithm to run (BFS, A* with number of misplaced tiles heuristic, A*
with Manhattan distance heuristic). The output method will return the path, path
cost, the number of nodes generated and the visualization of the path.
This class main purpose is to draw bar chart to visualize the average path cost,
average time cost (seconds), and average number of nodes generated.
The Number of misplaced tiles heuristic counts the number of tiles not in correct
position of the goal state. It is both admissible and consistent for the 8 puzzle
problem.
• Admissibility: The number of misplaced tiles heuristic is admissible since every
misplaced tile requires at least one move to get back to its correct spot, and
every move contributes to solving the puzzle, the number of misplaced tiles
directly represents the minimum number of moves needed to solve the 8
puzzle.
• Consistency: The number of misplaced tiles heuristic is consistent as for an
arbitrary state of the 8 puzzle, we make a valid move and move that state to
the neighboring state, the number of misplaced tiles can only decrease by at
most one (since at most one misplaced tile can be corrected in one move). And
also the cost to reach a successor state is always equal the cost to reach the
current state plus one. Hence, the heuristic satisfies the consistency property.
The Manhattan distance heuristic calculates the sum of the Manhattan distances
between each tile’s current position and its goal position.. It is both admissible and
consistent for the 8 puzzle problem.
• Admissibility: The Manhattan distance heuristic calculates the sum of the
distances (in terms of rows and columns) that each tile is away from its
desired position, ignoring any obstacles. Since each tile must move at least the
number of squares equal to its Manhattan distance to reach its goal position,
the Manhattan distance heuristic always underestimates the actual cost.
Therefore, it is admissible for the 8 puzzle problem.
• Consistency: the Manhattan distance is the sum of horizontal and vertical
distances, moving a tile one step closer to its goal reduces its Manhattan
distance by at least one. Therefore, the total Manhattan distance from the
start state to the goal state strictly decreases as we move towards the goal
making the heuristic consistent.
• Contains information about the maze (the current status of a maze to print).
• Check the status of a position in a maze (is wall?, is food?, etc.)
• Provide the method to get the food locations and the corners for each the
maze layout file.
• Take the initial state and initialize the problem for the search.
• Methods:
• get actions: take the problem and return the list of actions and nodes from initial
state to final goal
Algorithm 4 ucs(problem:Problem)
0: expanded ← set(); frontier ← PriorityQueue()
0: frontier .push(problem.initial state, 0)
0: while !frontier .isEmpty() do
0: node ← frontier .pop()
0: if problem.goal test(node) then
0: return find path(node)
0: end if
0: expanded.add(node.get id())
0: for successor in problem.get successors(node) do
0: if successor .get id() not in expanded or successor .path cost <
node.path cost then
0: frontier .push(successor , successor .path cost)
0: parents[successor .get id()] = node
0:
0:
return path
One of the solution we have tried is to get the Manhattan distance from the
current position to the nearest food dot as the heuristic for each point.
The Minimum Spanning Tree (MST) heuristic provides a lower bound on the cost
to eat all the remaining food. It treats each food pellet as a node in a graph and
calculates the weight of the MST that connects all these nodes, including pacman’s
current position.