1

我正在尝试对以下的每个结果执行求和运算:

combination(0,_,[]).
combination(K,L,[X|Xs]) :-
   K > 0,
   el(X,L,R),
   K1 is K-1,
   combination(K1,R,Xs).

el(X,[X|L],L).
el(X,[_|L],R) :- el(X,L,R).

例如,用户将输入 is_sum_equal_10 ([1,2,3,4,5,6,7]),如果任何排列之和等于 10,则结果将为真。

我正在努力将它们放在一起,有人可以帮我定义为每个排列使用组合规则的 is_sum_equal_10 规则吗?

4

1 回答 1

2

好吧,这真的很容易写,你只需要一个规则来说明一个特定的组合是否总和为 10,然后再增加一个额外的一个来计算不同大小的组合列表(由于你编写的方式,这是必需的与您在检查规则时需要减少的 K 组合)。

1 ?- [user].
|: combination(0,_,[]).
|: combination(K,L,[X|Xs]) :- K > 0,
|:    el(X,L,R), K1 is K-1, combination(K1,R,Xs).
|: el(X,[X|L],L).
|: el(X,[_|L],R) :- el(X,L,R).
|: 
|: totals_10([],10).
|: totals_10([X|Xs],T) :- N is T+X, totals_10(Xs,N).
|: 
|: is_comb_sum_equal_10(Numbers,_,R) :- combination(R,Numbers,C), totals_10(C,0).
|: is_comb_sum_equal_10(Numbers,N,R) :- Rnext is R+1, Rnext =< N,
|:    is_comb_sum_equal_10(Numbers,N,Rnext).
|: 
|: is_sum_equal_10(Numbers) :- length(Numbers,N), is_comb_sum_equal_10(Numbers,N,0).
|: 
% user://1 compiled 0.13 sec, 1,824 bytes
true.

2 ?- is_sum_equal_10([2,3,5]).
true .

3 ?- is_sum_equal_10([2,235,124,3,3347,5,2373]).
true .

4 ?- is_sum_equal_10([2,235,124,3,3347,6,2373]).
false.

5 ?- is_sum_equal_10([1,1,1,1,1,-1,1,1,1,1,12]).
false.

6 ?- is_sum_equal_10([1,1,1,1,1,-1,1,1,1,1,11]).
true ;
false.

由于您不关心实际列表或它在 is_sum_equal_10 事物中的大小,因此您可以在进行时对组合进行求和,甚至更好的是,检查总和是否正确作为基本情况的规则。我认为,如果您从所需的总数中减去以在基数处达到 0,而不是加起来并在最后检查您想要的值,这会更简洁一些。这为您提供了一个非常简单的单一规则集来查找某个总和。

7 ?- [user].
|: is_subset_sum(0,[]).
|: is_subset_sum(N,[_|Xs]) :- is_subset_sum(N,Xs).
|: is_subset_sum(N,[X|Xs]) :- R is N-X, is_subset_sum(R,Xs).
|: 
% user://2 compiled 0.03 sec, 540 bytes
true.

8 ?- is_subset_sum(10,[3,5,6]).
false.

9 ?- is_subset_sum(10,[123,4,1,77,3,2,34]).
true .

10 ?- is_subset_sum(11,[0,2,4,6,8,10,12,14,16,18,20,22]).
false.

这种方法当然更容易理解,也更有效。

于 2009-12-13T06:31:02.990 回答