2

我正在尝试使用 Prolog 解决“传教士和食人族”问题,在该问题中,您在岛屿的一侧输入了传教士和食人族的数量,并且他们必须乘坐一艘指定的船穿越到另一侧最大容量,约束为:

  1. 在岛的两侧和船上,食人者的人数不能超过传教士。

  2. 船上必须至少有一个人。

我试图用以下代码来实现这一点:

    % M = number of missionaries
    % C = number of cannibals

    % AM = number of missionaries on left island
    % BM = number of missionaries on right island

    % AC = number of cannibals on left island
    % BC = number of cannibals on right island

    % B = 1 if boat is on left island, -1 if boat is on right island
    % L = list of previous states / moves
    % K = maximum capacity of boat

上面所有变量的键:

    checkIsland(M,C) :- C =< M.

    checkState(AM, AC, BM, BC) :-
        checkIsland(AM, AC),
        checkIsland(BM, BC).

    checkMove(AM,AC,BM,BC,B,L):-
        checkState(AM,AC,BM,BC),
        not(member([AM,AC,BM,BC,B],L)).

    checkBoat(M,C,K) :-
        C =< M,
        (M + C) =< K,
        (M + C) >= 1.

    state(_,0,0,_,_,-1,_).
    state(K,AM,AC,BM,BC,B,L) :-
        % checkMove(NewAM, NewAC, NewBM, NewBM, NewB, L),
        abs((NewAM - NewBM), FinalM),
        abs((NewAC - NewBC), FinalC),           
        checkBoat(FinalM, FinalC),
        append([AM,AC,BM,BC,B], L, NewL),
        state(K,NewAM, NewAC,NewBM,NewBC,NewB,NewL).

我认为我非常接近,主要(唯一?)问题在于该state功能,因为我不明白您应该如何生成可能的动作/实际进行动作。有人可以请教。

我正在尝试使用上述功能专门解决它,因为它是过去的试卷问题。

编辑:

为了阐明state/7谓词的目的,它用于查找并输出通过求解过程发生的所有状态的列表。例如。

如果你打电话state(2,2,1,0,0,1,[])(上面说左边岛上有一艘容量为 2 的船,左边岛上有两个传教士和一个食人族,右边岛上有零传教士和零个食人族),然后打印出结果L 最终可能会给出:

2, 1, 0, 0, 1    % The initially input state
1, 0, 1, 1, -1   % 1 missionary, 1 cannibal and the boat move to the right island
1, 1, 1, 0, 1    % 1 cannibal and the boat move to the left island
0, 0, 2, 1, -1   % 1 missionary, 1 cannibal and the boat move to the right island,
                   and the goal is met
4

0 回答 0