问题
I am trying to solve the 'missionaries and cannibals' problem using Prolog, in which you have an input number of missionaries and cannibals on one side of an island, and they have to all cross to the other side in a boat that has a specified maximum capacity, with the constraint of:
On either side of the island, and in the boat, cannibals cannot outnumber missionaries.
There has to be at least one person in the boat.
I have attempted to achieve this with the following code:
% 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
Key above for all variables that follow:
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).
I think I am fairly close, with the main (only?) issue being with the state
function, as I don't understand how you are supposed to generate the possible moves / actually make a move. Could someone please advise.
I am trying to solve it specifically using the functions above as it's a past exam paper question.
Edit:
To clarify the purpose of the state/7
predicate, it's used to find and output a list of all the states that occur through the solving process. For example.
If you call state(2,2,1,0,0,1,[])
(which says that there's a boat of capacity two on the left island, and that there are two missionaries and one cannibal on the left island, and zero missionaries and zero cannibals on the right island), then printing out the result of L may end up giving:
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
来源:https://stackoverflow.com/questions/54053834/generating-possible-combinations-in-prolog