I am using the NxN puzzle solution using the A * search algorithm and using Manhattan distance as a heuristic, and I came across a curious error (?) That I cannot circle around.
Consider these puzzles (0 is empty space):
(Initial)
1 0 2
7 5 4
8 6 3
(target)
1 2 3
4 5 6
7 8 0
The minimum number of steps to reach a solution from the initial state is 11. However, my solver reaches the goal in 17 moves.
And this is the problem - my puzzle solves mainly solvable puzzles in the correct (minimum) number of moves, but for this particular puzzle my solver over-performs the minimum number of moves, and I think I nailed the problem to the calculation of the Manhattan distance in this particular case.
On this you can see what my solver does (on the right) and what the proven n-test solver does (Brian Borowski is an excellent solver available here ).
In the very first step, Brian solver immediately selects a solution that pushes element 5 up, but my solver has other ideas, and on the stack (on link ), my solver chooses a solution that pushes 2 to the left (since the distance to Manhattan on board is less , the board is on the front of the priority queue). I donโt see what the problem is, and I canโt blame my calculation of the Manhattan distance, since it correctly solves a number of other 3x3 puzzles.
Here's how I calculate the Manhattan distance of a given Rules:
/** * Calculates sum of Manhattan distances for this board and stores it in private field to promote immutability. */ private void calculateManhattanDistance() { int manhattanDistanceSum = 0; for (int x = 0; x < N; x++) // x-dimension, traversing rows (i) for (int y = 0; y < N; y++) { // y-dimension, traversing cols (j) int value = tiles[x][y]; // tiles array contains board elements if (value != 0) { // we don't compute MD for element 0 int targetX = (value - 1) / N; // expected x-coordinate (row) int targetY = (value - 1) % N; // expected y-coordinate (col) int dx = x - targetX; // x-distance to expected coordinate int dy = y - targetY; // y-distance to expected coordinate manhattanDistanceSum += Math.abs(dx) + Math.abs(dy); } } manhattanDistance = manhattanDistanceSum; }
I would appreciate any ideas or ideas you may have.
If any additional code is needed, I will send it right away.
quantum
source share