2

对于我的程序,我需要制作一个列表列表,每个子列表包含 2 个数字 X 和 Y 以及这两个数字的总和和乘积。到目前为止,我有以下内容:

genList(95, X,[]):-!.
genList(N, X,[[X,Y,Sum,Product]|Xs]):-
    Y is N+1,
    Sum is X+Y,
    Sum<101,
    Product is X*Y,
    N1 is N+1,
    genList(N1, X,Xs).

这适用于我的 genList(5,5,Q) 测试用例。但是,我无法使其适用于任何起始号码。

目标是找到 sum<= 100 的每一对数字。因此,对于一个起始值,X 将找到每一对 1 < X < Y,其中 sum<=100,并用所有数字 2 遍历它-N 将给出可能对的完整列表。

对于那些感兴趣的人,我正在解决的问题是总和/乘积问题,在这里描述(第二页)

如果有人可以提供帮助,将不胜感激!

此外,无法使用内置的 prolog 谓词,因此执行此操作的方法很复杂,而不是使用 findall。

此谓词产生的输出的一小部分摘录如下:

[[5,6,11,30],[5,7,12,35],[5,8,13,40],[5,9,14,45],[5,10,15,50] ,[5,11,16,55],[5,12,17,60],[5,13,​​18,65],[5,14,19,70],[5,15,20,75] ,[5,16,21,80],[5,17,22,85],[5,18,23,90],[5,19,24,95],[5,20,25,100],[ 5,21,26,105],[5,22,27,110], ...

编辑:

好的,所以经过一些编辑,这是我的代码的最新版本。

我认为它非常接近,但仍有一些不太对劲的地方。

它在数字对中循环,但需要使用“;” 查看所有答案,这不是我想要的。此外,在所有答案都用完后,它会返回 false。我就是想不通。

此外,它在中间给出了一个完整的答案,但每次都会删除一个子列表,直到我只剩下最后一组对。

例如 genList(0,48,48,Q)。给我:

[[48,49,97,2352],[48,50,98,2400],[48,51,99,2448],[48,52,100,2496]]
[[48,49,97,2352],[48,50,98,2400],[48,51,99,2448],[48,52,100,2496],[49,50,99,2450],[49,51,100,2499]]
[[48,49,97,2352],[48,50,98,2400],[48,51,99,2448],[49,50,99,2450],[49,51,100,2499]]
[[48,49,97,2352],[48,50,98,2400],[49,50,99,2450],[49,51,100,2499]]
[[48,49,97,2352],[49,50,99,2450],[49,51,100,2499]]
[[49,50,99,2450],[49,51,100,2499]]
false.

如您所见,每次都会删除一个子列表,我就是不明白为什么!

4

2 回答 2

1

我感觉你以错误的方式解决问题;我必须承认我真的不明白你的谓词在做什么。

目标是找到 sum<= 100 的每一对数字。

假设您的意思是无序的非负整数对,那就是

between(0, 100, Sum),
between(0, Sum, X),
Y is Sum - X,
X =< Y.

然后可以用 构造所有此类对的集合(作为列表)findall/3

您也可以使用 CLP(fd) 执行此操作:

use_module(library(clpfd)).
[X, Y, Sum] ins 0..100,
X #=< Y,
X + Y #= Sum,
label([X,Y,Sum]).
于 2012-04-09T13:31:36.163 回答
1

您可以在此处利用 Prolog 回溯。只要说出你想要的。例如你可以说:

  • 我想X介于1和之间100
  • 我想Y介于1和之间min(100 - X, X)
  • 然后我想要他们的一对

让我们看看validPair/1谓词是什么样的:

validPair(X-Y) :-
    between(1, 100, X),
    Limit is min(100 - X, X),
    between(1, Limit, Y).

你可以用它来调用它

?- validPair(X).

并使用 浏览结果;,或使用 构建所有匹配对的列表findall/3

编辑:即使使用递归,我们也可以保留我们的语句:

  • 我想X介于1和之间100
  • 我想Y介于1和之间min(100 - X, X)
  • 然后我想要他们的一对

因此,这样做的一个想法是设置一个工作者谓词:

validPair(Result) :-
    validPair(0, 0, Result).
validPair(X, Y, R) :-
    ...

然后设置基本情况:

validPair(101, _Y, []) :- !.

在 worker 谓词中,实现我们在某些条件下所做的语句:

validPair(X, Y, [SomeStuff|R]) :-
    X =< 100,
    Limit is min(100 - X, X),
    Y =< Limit,
    !,
    % we can go on and increment Y once we're finished
    validPair(X, NextY, R).
validPair(X, Y, R) :-
    % if we come here that means that Y is finished growing and
    % we have to increment X
    NextX is X + 1,
    validPair(NextX, 0, R).
于 2012-04-09T13:33:56.137 回答