- added test for 8-Puzzle
This commit is contained in:
2024-01-10 12:42:13 +01:00
parent af825cc174
commit 569f902126
2 changed files with 31 additions and 15 deletions

View File

@@ -5,6 +5,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.function.BiFunction;
/**
* Classe utilizzata per la rappresentazione del problema delle 8 tessere.
@@ -17,6 +18,20 @@ import java.util.Random;
public class Puzzle8 implements Iterable<Integer> {
public static final int LENGTH = 3;
public static final int[] DEFAULT_GOAL = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 0};
public static final BiFunction<Puzzle8, Puzzle8, Integer> HEURISTIC_MANHATTAN = (p1, p2) -> {
var sum = 0;
var n = p1.puzzle.length;
var index = new int[n];
for(var i = 0; i < n; i++) index[p1.puzzle[i]] = i;
for(var i = 0; i < n; i++) {
var curr = p2.puzzle[i];
var i2 = index[curr];
sum += Math.abs((i / LENGTH) - (i2 / LENGTH)) + Math.abs((i % LENGTH) - (i2 % LENGTH));
}
return sum;
};
/**
* Possibili movimenti della tessera "vuota"
@@ -250,21 +265,8 @@ public class Puzzle8 implements Iterable<Integer> {
public List<Move> solve(Puzzle8 goal) {
if(!this.isSolvable(goal)) return null;
var aStar = new AStar<Puzzle8, Move>(Puzzle8::availableMoves, (p, m) -> new Puzzle8(p, m))
.setHeuristic((p1, p2) -> {
var sum = 0;
var n = p1.puzzle.length;
var index = new int[n];
for(var i = 0; i < n; i++) index[p1.puzzle[i]] = i;
for(var i = 0; i < n; i++) {
var curr = p2.puzzle[i];
var i2 = index[curr];
sum += Math.abs((i / LENGTH) - (i2 / LENGTH)) + Math.abs((i % LENGTH) - (i2 % LENGTH));
}
return sum;
});
var aStar = new AStar<Puzzle8, Move>(Puzzle8::availableMoves, (p, m) -> new Puzzle8(p, m));
aStar.setHeuristic(HEURISTIC_MANHATTAN);
return aStar.solve(this, Objects.requireNonNull(goal));
}

View File

@@ -147,4 +147,18 @@ public class TestPuzzle {
assertEquals(puzzle, goal);
}
@Test
public void testSolveHard() {
var goal = new Puzzle8(Puzzle8.DEFAULT_GOAL);
var puzzle = new Puzzle8(0,5,2,4,1,7,3,8,6);
var actions = puzzle.solve().toArray(new Puzzle8.Move[0]);
for(var move : actions) puzzle.move(move);
assertEquals(puzzle, goal);
puzzle = new Puzzle8(0,8,3,7,5,2,6,1,4);
actions = puzzle.solve().toArray(new Puzzle8.Move[0]);
for(var move : actions) puzzle.move(move);
assertEquals(puzzle, goal);
}
}