序言中的水壶

发布于 2024-12-07 17:57:34 字数 1489 浏览 0 评论 0原文

这是一个水壶的问题。较大的桶可容纳 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).

It is a water jug problem. The larger bucket holds 5, the smaller bucket holds 3. I want to get 4 in the larger bucket.

The problem is that when I run I cannot get any answer, it produces an error. It doesn't seem like an obvious error, the algorithm is simple and direct.

Could anyone help me to find what is wrong with it?

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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

〃安静 2024-12-14 17:57:34

您没有使用“is”来进行作业。

您的 puzzle\0 谓词有两个未绑定变量: X & 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)]

显然倒数第二个(最短的)是最好的。

You're not using "is" for the assignments.

Your puzzle\0 predicate has two unbound variables: X & Y.

And your path\4 predicates are faulty.

Try these:

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.

Below is my solution to this problem:

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.

I get these solutions:

[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)]

Obviously the second to last, being the shortest, is the best.

许仙没带伞 2024-12-14 17:57:34

**

水壶问题:

**

%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).

**

**

Water Jug Problem:

**

%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).

**
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文