Prolog:使用A *来解决8个难题

时间:2017-05-11 17:12:32

标签: prolog graph-theory path-finding heuristics 8-puzzle

我试图实现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)truefalse是否可以解决该问题。

我还实施了两个启发式manhattan(+Board,+Goal,-H)hamming(+Board,+Goal,-H),用于计算从BoardGoal的启发式费用。例如:

?- 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的估算费用之和(由启发式函数定义)。当然,ClosedOpen是由A *算法维护的两个集合,其中Closed包含已访问过的板,Open包含没有的板。 / p>

问题是我不知道如何在Prolog中这样做。我想一些堆数据结构是维护这两个列表所必需的,但不知道是什么或如何。任何帮助都会很棒。

0 个答案:

没有答案