对于我的程序,我需要列出一个列表,每个子列表包含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)的测试用例。 但是,我无法使其适用于任何起始编号。
目标是找到总和<= 100的每对数字。因此,通过上面的一个起始值,X将找到每对1&lt; X&lt; Y,其中和<= 100,并且所有数字都是2-N,它将给出完整的可能对列表。
对于那些感兴趣的人,我正在解决的问题是总和/产品问题,描述为here(页面上的第二个)
如果有人可以提供帮助,我们将不胜感激!
此外,没有内置的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。我只是想不出来。
此外,它在中间给出了一个完整的答案,但每次都会删除一个子列表,直到我只剩下最后一组对。
E.g。 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.
正如您所看到的,每次都会删除子列表,我只是看不清楚原因!
答案 0 :(得分:1)
我有一种感觉,你是以错误的方式解决问题;我必须承认我并不真正理解你的谓词在做什么。
目标是找到总和<= 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]).
答案 1 :(得分: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).