2

这是我第一次来这里,我知道已经有关于这个的帖子,但似乎与我想编码的方式不同。我只是一直得到错误的答案。

我输入:solve(0,0). 结果是false.

代码。

solve(5,_).
solve(X,Y):- X < 7,
   \+ member((7,Y),L),  
   concat(E,[(X,Y)],L),
   write('Fill 7 litre jug from tap.\n'),
   solve(7,Y).
solve(X,Y):- Y < 4,
   \+ member((X,4),L),
   concat(E,[(X,Y)],L),
   write('Fill 4 litre jug from tap.\n'),
   solve(X,4).
solve(X,Y):- X+Y >= 7,
   Y > 0,
   Z is Y - (7 - X),
   \+ member((7,Z),L),
   concat(E,[(X,Z)],L),
   write('Fill 7 litre jug with 4 litre jug.\n'),
   solve(7,Z).
solve(X,Y):- X+Y >= 4,
   X > 0,
   Z is X - (4 - Y),
   \+ member((Z,4),L),
   concat(E,[(Z,Y)],L),
   write('Fill 4 litre jug with 7 litre jug.\n'),
   solve(Z,4).
solve(X,Y):- X+Y < 4,
   Y > 0,
   Z is X + Y,
   \+ member((Z,0),L),
   concat(E,[(Z,Y)],L),
   write('Empty 4 litre jug into 7 litre jug.\n'),
   solve(Z,0).
solve(X,Y):- X+Y < 7,
   X > 0,
   Z is X+Y,
   \+ member((0,Z),L),
   concat(E,[(X,Z)],L),
   write('Empty 7 litre jug into 4 litre jug.\n'),
   solve(0,Z).
solve(X,Y):- X > 0,
   \+ member((0,Y),L),
   concat(E,[(X,Y)],L),
   write('Empty 7 litre jug.\n'),
   solve(0,Y).
solve(X,Y):- Y > 0,
   \+ member((X,0),L),
   concat(E,[(X,Y)],L),
   write('Empty 4 litre jug.\n'),
   solve(X,0).

member(X,[X|L]).
member(X,[L|L]):- 
   member(X,L).

concat([],L,L).
concat([X|A],B,[X|L]):- 
   concat(A,B,L).

任何帮助深表感谢。谢谢。

4

1 回答 1

0

我猜您想通过避免循环进行简单的深度优先搜索。至少我将成员检查作为对搜索中现有循环的检查。

现在您的代码用于谓词solve/2,内容如下:

[..]
solve(X,Y):- X+Y < 4,
   Y > 0,
   Z is X + Y,
   \+ member((Z,0),L),
   concat(E,[(Z,Y)],L),
   write('Empty 4 litre jug into 7 litre jug.\n'),
   solve(Z,0).
[..]

问题是你没有传递 L 和 E。在查阅 Prolog 文本时,你也应该得到一个警告,它可能会说 E 是一个单例变量。

我想使用谓词solve/3 而不是谓词的解决方案solve/2会更好。您可以在第三个参数中传递已经访问过的状态。代码将如下所示:

[..]
solve(X,Y,L):- X+Y < 4,
   Y > 0,
   Z is X + Y,
   \+ member((Z,0),L),
   concat(E,[(Z,Y)],L),
   write('Empty 4 litre jug into 7 litre jug.\n'),
   solve(Z,0,E).
[..]

希望这可以帮助。

再见

PS: concat/3 不是必须的,直接说E = [(Z,0)|L],或者把 E 方程全部去掉,把里面的solve/3 的调用修改为solve(Z,0,[(Z,0)|L])

于 2014-04-09T01:27:52.180 回答