我正在尝试使用 Prolog 解决“传教士和食人族”问题,在该问题中,您在岛屿的一侧输入了传教士和食人族的数量,并且他们必须乘坐一艘指定的船穿越到另一侧最大容量,约束为:
在岛的两侧和船上,食人者的人数不能超过传教士。
船上必须至少有一个人。
我试图用以下代码来实现这一点:
% 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