Prolog 序言:使用*解决8个难题

Prolog 序言:使用*解决8个难题,prolog,graph-theory,path-finding,heuristics,sliding-tile-puzzle,Prolog,Graph Theory,Path Finding,Heuristics,Sliding Tile Puzzle,我正在尝试实现一个问题的求解器。拼图板用列表表示。例如,目标状态: 1 | 2 | 3 --------- 4 | 5 | 6 --------- 7 | 8 | 0 表示为[1,2,3,4,5,6,7,8,0],其中0表示空白 我已经实现了move(+Board,-move),它通过move成功,因为Board one的所有可能状态都从Board移开。此外,我还实现了solvable(+Board),它给出了true或false关于是否可以解决Board的问题 我还实现了两种启发式算法,ma

我正在尝试实现一个问题的求解器。拼图板用列表表示。例如,目标状态:

1 | 2 | 3
---------
4 | 5 | 6
---------
7 | 8 | 0
表示为
[1,2,3,4,5,6,7,8,0]
,其中
0
表示空白

我已经实现了
move(+Board,-move)
,它通过
move
成功,因为Board one的所有可能状态都从
Board
移开。此外,我还实现了
solvable(+Board)
,它给出了
true
false
关于是否可以解决Board的问题

我还实现了两种启发式算法,
manhattan(+Board,+Goal,-H)
hamming(+Board,+Goal,-H)
,它们计算从
Board
Goal
的启发式成本。例如:

?- 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.
?- 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]
].
我想实现
求解(+Board,+Heuristic,-Solution)
,它成功地使用
解决方案
作为
Board
的一个最佳解决方案,使用给定的
启发式
,并且它必须精确地以一个解决方案终止。例如:

?- 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.
?- 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]
].
我为A*算法编写了伪代码:

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}
对于板的每个子级,请执行以下操作:
如果儿童处于关闭状态,请执行以下操作:
继续
如果儿童未处于关闭状态或G(板)+1
其中
G(Board)
Board
的实际成本,定义为从初始板到
Board
的最佳路径的长度
F(Board)
Board
的组合成本,定义为
G(Board)
Board
的估计成本之和(由启发式函数定义)。当然,
Closed
Open
是由A*算法维护的两个集合,
Closed
包含已访问的板,
Open
包含未访问的板

问题是我不知道如何在Prolog中实现这一点。我认为需要一些堆数据结构来维护这两个列表,但不知道是什么或如何。任何帮助都会很好