I'm trying to implement a solver of an 8-puzzle. The puzzle board is represented as a list. For example, the goal state:
1 | 2 | 3
---------
4 | 5 | 6
---------
7 | 8 | 0
is represented as [1,2,3,4,5,6,7,8,0]
, where 0
represents the empty space.
I've implemented move(+Board,-Move)
that succeeds with Move
as all the possible states of the board one move away from Board
. In addition I've implemented solvable(+Board)
that gives true
or false
as to whether the board can be solved.
I've also implemented two heuristics, manhattan(+Board,+Goal,-H)
and hamming(+Board,+Goal,-H)
, which calculates the heuristics cost from Board
to Goal
. For example:
?- hamming([1,2,3,8,0,4,7,6,5],[1,2,3,8,0,4,7,6,5],H).
H = 0.
?- hamming([1,2,3,4,0,8,7,6,5],[1,2,3,8,0,4,7,6,5],H).
H = 2.
?- manhattan([1,2,3,8,0,4,7,6,5],[1,2,3,8,0,4,7,6,5],H).
H = 0.
?- manhattan([1,2,3,4,0,8,7,6,5],[1,2,3,8,0,4,7,6,5],H).
H = 4.
I want to implment solve(+Board,+Heuristic,-Solution)
that succeeds with Solution
as one optimal solution to Board
using the Heuristic
given, and it must terminate deterministically with precisely one solution. For example:
?- solve([0,1,3,4,2,5,7,8,6],manhattan,Solution).
Solution = [
[0, 1, 3, 4, 2, 5, 7, 8, 6],
[1, 0, 3, 4, 2, 5, 7, 8, 6],
[1, 2, 3, 4, 0, 5, 7, 8, 6],
[1, 2, 3, 4, 5, 0, 7, 8, 6],
[1, 2, 3, 4, 5, 6, 7, 8, 0]
].
I wrote out the pseudo code for the A* algorithm:
For each Child of Board do:
If Child in Closed do:
Continue
If Child not in Closed or G(Board) + 1 < G(Child) do:
G(Child) := G(Board) + 1
F(Child) := G(Child) + Heuristic(Child,Goal)
If Child not in Open do:
Open := Open + {Child}
Where G(Board)
is the actual cost of Board
, defined as the length of the optimal path to Board
from the initial board. F(Board)
is the combined cost of Board
, defined as the sum of G(Board)
and the estimated cost of Board
(defined by a heuristic function). And of course Closed
and Open
are the two sets maintained by the A* algorithm, with Closed
containing boards that have been visited, Open
containing boards that have not.
Issue is I have no idea how to do this in Prolog. I suppose that some heap datastructure is necessary to maintain the two list, but have no idea what or how. Any help would be great.