我试图实现8-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
。此外,我已实施solvable(+Board)
,true
或false
是否可以解决该问题。
我还实施了两个启发式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(+Board,+Heuristic,-Solution)
使用Solution
作为Board
的最佳解决方案成功Heuristic
,并且必须使用恰好一个解决方案确定性终止。例如:
?- 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(Board)
是Board
的实际成本,定义为从初始板到Board
的最佳路径的长度。 F(Board)
是Board
的合计费用,定义为G(Board)
与Board
的估算费用之和(由启发式函数定义)。当然,Closed
和Open
是由A *算法维护的两个集合,其中Closed
包含已访问过的板,Open
包含没有的板。 / p>
问题是我不知道如何在Prolog中这样做。我想一些堆数据结构是维护这两个列表所必需的,但不知道是什么或如何。任何帮助都会很棒。