AI Assignment #4 Submitted By: Bhaskar Vivek Agarwal Ques Given a start state and a goal state - solve the 8-puzzle problem. Consider it as a state space problem. Define state representations and the set of operators. While searching find the merit of the nodes and keep exploring the children of a given node by considering the generation and heuristic cost. Consider the following cost function: f(n)=g(n)+h(n). f(n) denotes how promising that node n is while searching for the goal node. Implement suitable heuristic function (number of misplaced-tiles/Manhattan distance) for solving the problem. Use appropriate data structure to implement the search algorithm. Solution: import java.util.*; public class EightPuzzleSolver { // Define the goal state and the initial state private static final int[][] goalState = {{1, 2, 3}, {4, 5, 6}, {7, 8, 0}}; // 0 represents the empty tile // Define possible moves (up, down, left, right) private static final int[][] moves = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; private static final String[] moveNames = {"Right", "Left", "Down", "Up"}; // Define a class to represent a state private static class State { int[][] state; int cost; int heuristic; State parent; String lastMove; public State(int[][] state, int cost, int heuristic, State parent, String lastMove) { this.state = state; this.cost = cost; this.heuristic = heuristic; this.parent = parent; this.lastMove = lastMove; } } // Calculate the Manhattan distance heuristic for a given state private static int manhattanDistance(int[][] state) { int distance = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (state[i][j] != 0) { int goalX = (state[i][j] - 1) / 3; int goalY = (state[i][j] - 1) % 3; distance += Math.abs(i - goalX) + Math.abs(j - goalY); } } } return distance; } // Check if a move is within bounds private static boolean isValidMove(int x, int y) { return x >= 0 && x < 3 && y >= 0 && y < 3; } // Apply a move to a state and return the new state private static int[][] applyMove(int[][] state, int[] move) { int[][] newState = new int[3][3]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { newState[i][j] = state[i][j]; } } int[] emptyPos = findEmptyTile(state); int emptyX = emptyPos[0]; int emptyY = emptyPos[1]; int newX = emptyX + move[0]; int newY = emptyY + move[1]; newState[emptyX][emptyY] = newState[newX][newY]; newState[newX][newY] = 0; return newState; } // Find the coordinates of the empty tile in the state private static int[] findEmptyTile(int[][] state) { int[] emptyPos = new int[2]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (state[i][j] == 0) { emptyPos[0] = i; emptyPos[1] = j; return emptyPos; } } } return emptyPos; } // Solve the 8-puzzle problem using A* search private static List<State> aStarSearch(int[][] initialState) { PriorityQueue<State> openSet = new PriorityQueue<>(Comparator.comparingInt(s -> s.cost + s.heuristic)); Set<State> closedSet = new HashSet<>(); Map<State, String> cameFrom = new HashMap<>(); State initial = new State(initialState, 0, manhattanDistance(initialState), null, ""); openSet.offer(initial); while (!openSet.isEmpty()) { State current = openSet.poll(); closedSet.add(current); if (Arrays.deepEquals(current.state, goalState)) { // Reconstruct the path List<State> path = new ArrayList<>(); while (current.parent != null) { path.add(current); current = current.parent; } Collections.reverse(path); return path; } int[] emptyPos = findEmptyTile(current.state); int emptyX = emptyPos[0]; int emptyY = emptyPos[1]; for (int i = 0; i < moves.length; i++) { int newX = emptyX + moves[i][0]; int newY = emptyY + moves[i][1]; if (isValidMove(newX, newY)) { int[][] newState = applyMove(current.state, moves[i]); State neighbor = new State(newState, current.cost + 1, manhattanDistance(newState), current, moveNames[i]); if (!closedSet.contains(neighbor) && !openSet.contains(neighbor)) { openSet.offer(neighbor); cameFrom.put(neighbor, moveNames[i]); } } } } return Collections.emptyList(); // No solution found } public static void main(String[] args) { // Example usage: int[][] initial = {{1, 2, 3}, {4, 0, 5}, {6, 7, 8}}; List<State> statesToGoal = aStarSearch(initial); if (!statesToGoal.isEmpty()) { System.out.println("Number of moves to reach the goal: " + statesToGoal.size()); System.out.println("Sequence of states:"); for (State state : statesToGoal) { for (int[] row : state.state) { System.out.println(Arrays.toString(row)); } System.out.println("Move: " + state.lastMove); System.out.println(); } } else { System.out.println("No solution found."); } } } Output The matrix is shown at every step also describing the move to be done.