这是一个水壶问题。较大的水桶容纳5个,较小的水桶容纳3个。我想在较大的桶中得到4个。
问题是,当我跑步时,我无法得到任何答案,它会产生错误。它似乎不是一个明显的错误,算法简单直接。
有人可以帮我找到它有什么问题吗?
check_safe(X,Y):- X>=0,X=<3,Y>=0,Y=<5.
%empty the 3 bucket
move(state(X,Y),state(0,Y)):- X>0,check_safe(0,Y).
%empty the 5 bucket
move(state(X,Y),state(X,0)):- Y>0,check_safe(X,0).
%fill the 3 bucket
move(state(X,Y), state(3,Y)):- X<3, X>=0,check_safe(3,Y).
%fill the 5 bucket
move(state(X,Y),state(X,5)):- Y>=0, Y<5,check_safe(X,5).
%transfer from 3 to 5 until the larger bucket is full
move(state(X,Y),state(NewX,5)):- X+Y>= 5, X>0,Y>=0, NewX=X+Y-5,check_safe(NewX,5).
%transfer from 3 to 5 until the smaller bucket is empty
move(state(X,Y),state(0,NewY)):- X+Y<5, X>0,Y>=0, NewY=X+Y,check_safe(0,NewY).
%transfer from 5 to 3 until the smaller is full
move(state(X,Y),state(3,NewY)):- Y>0,X>=0,X+Y>=5, NewY=Y+X-3,check_safe(3,NewY).
%transfer from 5 to 3 until the larger is empty
move(state(X,Y),state(NewX,0)):-Y>0,X>=0, X+Y<5, NewX=Y+X,check_safe(NewX,0).
path(X,X,_,[X]).
path(X,Y,BeenStates,Path):-
move(X,Somewhere),not(member(Somewhere,BeenStates)),
path(Somewhere,Y,[Somewhere|BeenStates],Path2), Path = [X|Path2].
puzzle:- path(state(0,0),state(0,5),[state(0,0)],PathList),X>=0,X=<5,
writeOut(PathList).
% Here's an easy little predicate for printing a list.
writeOut([]).
writeOut([H|T]):-write(H),nl, writeOut(T).
答案 0 :(得分:5)
你没有在作业中使用“是”。
您的puzzle\0
谓词有两个未绑定的变量:X
&amp; Y
。
你的path\4
谓词有问题。
试试这些:
path([state(X, 4)|Xs],[state(X, 4)|Xs]):- !.
path([X|Xs],Rs):-
move(X,Y),not(member(Y,[X|Xs])),
path([Y,X|Xs],Rs).
puzzle:- path([state(0,0)],PathList),
write(PathList), nl, fail.
以下是我对此问题的解决方案:
move(s(X,Y),s(Z,5)) :- Z is X - (5 - Y), Z >= 0.
move(s(X,Y),s(Z,0)) :- Z is X + Y, Z =< 3.
move(s(X,Y),s(3,Z)) :- Z is Y - (3 - X), Z >=0.
move(s(X,Y),s(0,Z)) :- Z is X + Y, Z =< 5.
move(s(0,Y),s(3,Y)).
move(s(X,0),s(X,5)).
move(s(X,Y),s(X,0)) :- Y > 0.
move(s(X,Y),s(0,Y)) :- X > 0.
moves(Xs) :- moves([s(0,0)],Xs).
moves([s(X0,Y0)|T], [s(X1,4),s(X0,Y0)|T])
:- move(s(X0,Y0),s(X1,4)), !.
moves([s(X0,Y0)|T],Xs) :-
move(s(X0,Y0),s(X1,Y1)),
not(member(s(X1,Y1),[s(X0,Y0)|T])),
moves([s(X1,Y1),s(X0,Y0)|T],Xs).
?- moves(Xs), write(Xs), nl, fail.
我得到了这些解决方案:
[s(0,4),s(3,1),s(0,1),s(1,0),s(1,5),s(3,3),s(0,3),s(3,0),s(0,0)]
[s(3,4),s(2,5),s(2,0),s(0,2),s(3,2),s(0,5),s(1,5),s(3,3),s(0,3),s(3,0),s(0,0)]
[s(3,4),s(2,5),s(2,0),s(0,2),s(3,2),s(0,5),s(3,5),s(3,0),s(0,0)]
[s(0,4),s(3,1),s(0,1),s(1,0),s(1,5),s(3,3),s(0,3),s(3,0),s(3,2),s(0,5),s(0,0)]
[s(3,4),s(2,5),s(2,0),s(0,2),s(3,2),s(0,5),s(0,0)]
[s(0,4),s(3,1),s(0,1),s(1,0),s(1,5),s(3,3),s(0,3),s(3,0),s(3,5),s(0,5),s(0,0)]
显然,倒数第二,是最短的,是最好的。
答案 1 :(得分:0)
**
水壶问题:
**
%database
visited_state(integer,integer).
%predicates
state(integer,integer).
%clauses
state(2,0).
state(X,Y):- X < 4,
not(visited_state(4,Y)),
assert(visited_state(X,Y)),
write("Fill the 4-Gallon Jug: (",X,",",Y,") --> (", 4,",",Y,")\n"),
state(4,Y).
state(X,Y):- Y < 3,
not(visited_state(X,3)),
assert(visited_state(X,Y)),
write("Fill the 3-Gallon Jug: (", X,",",Y,") --> (", X,",",3,")\n"),
state(X,3).
state(X,Y):- X > 0,
not(visited_state(0,Y)),
assert(visited_state(X,Y)),
write("Empty the 4-Gallon jug on ground: (", X,",",Y,") --> (", 0,",",Y,")\n"),
state(0,Y).
state(X,Y):- Y > 0,
not(visited_state(X,0)),
assert(visited_state(X,0)),
write("Empty the 3-Gallon jug on ground: (", X,",",Y,") --> (", X,",",0,")\n"),
state(X,0).
state(X,Y):- X + Y >= 4,
Y > 0,
NEW_Y = Y - (4 - X),
not(visited_state(4,NEW_Y)),
assert(visited_state(X,Y)),
write("Pour water from 3-Gallon jug to 4-gallon until it is full: (", X,",",Y,") --> (", 4,",",NEW_Y,")\n"),
state(4,NEW_Y).
state(X,Y):- X + Y >=3,
X > 0,
NEW_X = X - (3 - Y),
not(visited_state(X,3)),
assert(visited_state(X,Y)),
write("Pour water from 4-Gallon jug to 3-gallon until it is full: (", X,",",Y,") --> (", NEW_X,",",3,")\n"),
state(NEW_X,3).
state(X,Y):- X + Y>=4,
Y > 0,
NEW_X = X + Y,
not(visited_state(NEW_X,0)),
assert(visited_state(X,Y)),
write("Pour all the water from 3-Gallon jug to 4-gallon: (", X,",",Y,") --> (", NEW_X,",",0,")\n"),
state(NEW_X,0).
state(X,Y):- X+Y >=3,
X > 0,
NEW_Y = X + Y,
not(visited_state(0,NEW_Y)),
assert(visited_state(X,Y)),
write("Pour all the water from 4-Gallon jug to 3-gallon: (", X,",",Y,") --> (", 0,",",NEW_Y,")\n"),
state(0,NEW_Y).
state(0,2):- not(visited_state(2,0)),
assert(visited_state(0,2)),
write("Pour 2 gallons from 3-Gallon jug to 4-gallon: (", 0,",",2,") --> (", 2,",",0,")\n"),
state(2,0).
state(2,Y):- not(visited_state(0,Y)),
assert(visited_state(2,Y)),
write("Empty 2 gallons from 4-Gallon jug on the ground: (", 2,",",Y,") --> (", 0,",",Y,")\n"),
state(0,Y).
goal:-
makewindow(1,2,3,"4-3 Water Jug Problem",0,0,25,80),
state(0,0).
**
> Output:
state(2,5).
**