gpt4 book ai didi

prolog - 如何验证坐标是否在列表中

转载 作者:行者123 更新时间:2023-12-02 07:22:36 24 4
gpt4 key购买 nike

我正在生成随机坐标并添加到我的列表中,但首先我需要验证该坐标是否已经存在。我正在尝试使用 member 但在调试时我发现它不起作用:

我的代码基本上是这样的:

% L is a list and Q is a count that define the number of coordinate
% X and Y are the coordinate members
% check if the coordniate already exists
% if exists, R is 0 and if not, R is 1
createCoordinates(L,Q) :-
random(1,10,X),
random(1,10,Y),
convertNumber(X,Z),
checkCoordinate([Z,Y],L,R),
(R is 0 -> print('member'), createCoordinates(L,Q); print('not member'),createCoordinates(L,Q-1).

checkCoordinate(C,L,R) :-
(member(C,L) -> R is 0; R is 1).

% transforms the number N in a letter L
convertNumber(N,L) :-
N is 1, L = 'A';
N is 2, L = 'B';
...
N is 10, L = 'J'.

%call createCoordinates
createCoordinates(L,20).

当我调试时,这是输出:

debugging

在这张图片中,我处于第一次交互中,L 为空,因此 R 应该为 1 但始终为 0,坐标始终是列表的一部分。我的印象是 member 子句在我的列表中添加坐标并且没有意义

最佳答案

首先,我建议将您的问题分解成更小的部分。你应该有一个制作随机坐标的过程:

random_coordinate([X,Y]) :- 
random(1, 10, XN), convertNumber(XN, X),
random(1, 10, Y).

其次,您的 checkCoordinate/3 正在将 Prolog 的成功/失败转换为整数,这只是 Prolog 的繁忙工作,并没有真正改善您的生活。 memberchk/2 完全足以完成您的任务(member/2 也可以,但比必要的更强大)。这里真正的问题不是 member/2 没有工作,而是你试图在出路时建立这个列表参数,但你需要它存在于检查的路上

在 Prolog 中,我们通常通过添加第三个参数并在处理过程中将值添加到列表中来解决此类问题。然后,基本情况将该列表与出站列表等同起来,我们使用较低级别的程序保护整个列表。换句话说,我们这样做:

random_coordinates(N, Coordinates) :- random_coordinates(N, [], Coordinates).

random_coordinates(0, Result, Result).
random_coordinates(N, CoordinatesSoFar, FinalResult) :- ...

现在我们有两件事,memberchk/2 应该按照我们需要的方式工作:

random_coordinates(N, CoordinatesSoFar, FinalResult) :- 
N > 0, succ(N0, N), % count down, will need for recursive call
random_coordinate(Coord),
(memberchk(Coord, CoordinatesSoFar) ->
random_coordinates(N, CoordinatesSoFar, FinalResult)
;
random_coordinates(N0, [Coord|CoordinatesSoFar], FinalResult)
).

这似乎符合我们的要求:

?- random_coordinates(10, L), write(L), nl.
[[G,7],[G,3],[H,9],[H,8],[A,4],[G,1],[I,9],[H,6],[E,5],[G,8]]

?- random_coordinates(10, L), write(L), nl.
[[F,1],[I,8],[H,4],[I,1],[D,3],[I,6],[E,9],[D,1],[C,5],[F,8]]

最后,我注意到您继续使用此语法:N is 1, ...。我警告你,这对我来说看起来像是一个错误,因为 this 和 N = 1 之间没有区别,而且你的谓词可能只是用这个来陈述有点令人厌烦:

convertNumber(1, 'A').
convertNumber(2, 'B').
...

我倾向于使用 char_code/2 进行计算,但实际上这种结构可能更好。

另一个表明您做错事的提示是,createCoordinates/2 的参数 L 在所有情况下都会传递,但在任何情况下都不会被检查。在 Prolog 中,我们经常有看起来只是毫无意义地传递的变量,但它们通常会改变位置或被多次使用,如 random_coordinates(0, Result, Result);虽然那里似乎什么都没有发生,但实际发生的是管道:构建的参数成为结果值。那里的变量没有发生任何有趣的事情,但它正在被探测。但是您的代码中的 L 什么也没有发生,除了据说正在检查它是否有新坐标。但实际上您从来没有向它附加任何内容,因此没有理由期望任何内容都会在 L 中结束。

编辑 请注意,@lambda.xy.x 通过在子句头部添加新坐标并仅在正文中递归调用之后检查列表来解决他们答案中的问题,避免需要第二个列表参数。

编辑 2 另请查看 @lambda.xy.x 的其他解决方案,因为它在 N 接近 100 时具有更好的时间复杂度。

关于prolog - 如何验证坐标是否在列表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41697608/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com