子集和Prolog

时间:2015-12-17 16:12:09

标签: list prolog sum subset subset-sum

定义一个谓词子集(L,Sum,Subl),它取一个数字列表L,一个数字Sum,并用一个子序列L统一SubL,使得SubL中的数字之和为Sum。

例如

   ?- subsetsum([1,2,5,3,2], 5, SubSet);

   SubSet = [1,2,2];
   SubSet = [2,3]; 
   SubSet = [5]; 
   SubSet = [3,2];

No.

我们有

 sum([H1 | [H2 | Tail]], S):-
   sum([[H1+H2]|Tail], S):-
 sum([X], X).

  subset([],[]).
  subset([H1|T1], [H1|T2]) :-  // heads are the same
    subset(T1, T2).
  subset([_|Rest], X):
    subset(Rest, X).

3 个答案:

答案 0 :(得分:2)

如果使用的所有数字都是整数且Prolog处理器支持,请按以下步骤操作!

:- use_module(library(clpfd)).

z_z_product(A,B,AB) :-
   AB #= A*B.

subsetsum_(Zs, Sum, Bs, [Sum|Vs]) :-
   same_length(Zs, Bs),
   append(Zs, Bs, Vs),
   Bs ins 0..1,
   maplist(z_z_product, Zs, Bs, Xs),
   sum(Xs, #=, Sum).

示例查询:

?- subsetsum_([1,2,5,3,2], 5, Sel, Vs), labeling([], Vs).
   Sel = [0,0,0,1,1], Vs = [5,1,2,5,3,2,0,0,0,1,1]
;  Sel = [0,0,1,0,0], Vs = [5,1,2,5,3,2,0,0,1,0,0]
;  Sel = [0,1,0,1,0], Vs = [5,1,2,5,3,2,0,1,0,1,0]
;  Sel = [1,1,0,0,1], Vs = [5,1,2,5,3,2,1,1,0,0,1]
;  false.

答案 1 :(得分:1)

以下条款应该做你需要的......

subsetsum(SET, SUM, ANSWER) :-
    % Find a subset
    subset(SET, ANSWER),
    % Check elements of the subset add up to SUM
    sum(ANSWER, SUM).

% sum(LIST, SUM) - sums all numbers in the list
sum([], 0).
sum([X | T], SUM) :-
    sum(T, TAILSUM),
    SUM is TAILSUM + X.

% subset - finds subsets
subset([], []).
subset([E|Tail], [E|NTail]) :-
    subset(Tail, NTail).
subset([_|Tail], NTail) :-
    subset(Tail, NTail).

答案 2 :(得分:1)

使用,我们可以将库谓词sum_list/2与您已经拥有的subset/2一起使用!请注意,我为subset/2提供了更合适的名称list_subsequence/2

list_subsequence([], []).
list_subsequence([X|Xs], [X|Ys]) :-
   list_subsequence(Xs, Ys).
list_subsequence([_|Xs], Ys) :-
   list_subsequence(Xs, Ys).

subsetsum(List, Sum, Sub) :-
   list_subsequence(List, Sub),
   sum_list(Sub, Sum).

以下是您提供的示例查询:

?- subsetsum([1,2,5,3,2], 5, Xs).
   Xs = [1,2,2]
;  Xs = [2,3]
;  Xs = [5]
;  Xs = [3,2]
;  false.

好的!让我们用整数和浮点运行另一个查询......这样做也有效吗?

?- subsetsum([1,2.1,5,3,2], 5.1, Xs).
   Xs = [1,2.1,2]
;  Xs = [2.1,3]
;  false.

对我来说没问题!