这是问题陈述:
给定整数L和整数S的列表,生成所有子列表 其元素加起来为S.
这是我的解决方案:
domains
list=integer*
clist=list*
predicates
sum(list,integer)
check(clist,clist,integer)
gensub(list,list)
getsub(list,clist,integer)
clauses
%gets all possible subsets with gensub and findall, binds them to
%and then checks the subsets to see if the elements add up to S
%and adds the correct ones to Rez.
%Goal example: getsub([1,2,5,6],X,7)
getsub([], [], _).
getsub(L, Rez, S):-
findall(LR, gensub(L,LR), X),
check(X, Rez, S).
%generates all possible subsets of the given set
gensub([], []).
gensub([E|Tail], [E|NTail]):-
gensub(Tail, NTail).
gensub([_|Tail], NTail):-
gensub(Tail, NTail).
%checks if the sum of the elements of a list is S
sum([], S):-S=0.
sum([H|T], S):-
N=S-H,
sum(T, N).
%checks if each sublist of a given list of lists, has the sum of elements S
check([], [], S).
%the LR variable here gives a warning after entering the goal
check([H|T], [H|LR], S):-
sum(H, S).
所以在我运行它之后我被问到了目标,我尝试getsub([1,2,5,6],X,7)
这样我得到的元素总数为7的所有子集,但我得到No Solution
,和
对check子句中的LR
变量发出警告,该变量未绑定。
我不确定我做错了什么,或者是否有更简单的解决方案。
任何帮助表示赞赏。
答案 0 :(得分:3)
我认为你的上一个程序应该是
%checks if each sublist of a given list of lists, has the sum of elements S
check([], [], _).
%the LR variable here gives a warning after entering the goal
check([H|T], [H|LR], S):-
sum(H, S),
!, check(T, LR, S).
check([_|T], LR, S):-
check(T, LR, S).
然后,请注意:
-
% sum elements of a list
sum([], 0).
sum([H|T], S):-
sum(T, N),
S is N+H.
(事实上,我使用这个测试,得到[[1,6],[2,5]]
)
答案 1 :(得分:2)
在这个答案中,我们使用clpfd:
:- use_module(library(clpfd)).
要了解所有可能的子列表,我们使用sublist_of/2
:
sublist_of(Sub,List) :-
list_sub(List,Sub).
sublist_of/2
基于辅助谓词list_sub/2
:
list_sub([] ,[]).
list_sub([_|Xs],Ys) :-
list_sub(Xs,Ys).
list_sub([X|Xs],[X|Ys]) :-
list_sub(Xs,Ys).
让我们把它放在一起!
list_sublist_sum(Xs,Zs,Sum) :-
sublist_of(Zs,Xs),
sum(Zs,#=,Sum).
示例查询:
?- list_sublist_sum([3,34,4,12,5,2],Zs,9).
Zs = [4,5]
; Zs = [3,4,2]
; false.