2009-12-13 89 views
1

我想对每一个结果进行求和运算:Prolog的语法 - 使用功能导致

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规则,每个规则使用组合规则排列?

回答

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. 

这种方法当然更容易理解,并且效率更高。

+0

谢谢,KernelJ,为这样一个详细的答案。还有一件事 - 为了简化任务 - 我想将置换大小设置为5的预定义值。因此,每次只检查给定列表中5个整数的置换集合是否总和最多10个。 我试图将R值设置为5,但我一直对任何计算尝试都得到错误的答案。给定输入列表的未知长度,我需要更改哪个值以检查每次尝试设置的固定排列大小? 谢谢你的帮助! Amy – Amy 2009-12-13 15:12:10

+0

我觉得很明显,如何根据已经存在的代码制定新的规则,您只需在规则中使用组合和totals_10即可。这是一条线!自己写一下;如果您仍然遇到麻烦,请发布您尝试的类型,然后或许我可以找出您不明白的部分。 – KernelJ 2009-12-13 16:04:43

+0

我试过的是增加一行: is_comb_sum_equal_10(Numbers,_,5): - combination(5,Numbers,C),totals_10(C,0)。 现在我只是用新行代替了最初的行(有5行而不是R行)。工作!:) 除了它,如果我想添加另一个条件,我可以写一个新函数first_2_last ,然后将条件添加到同一行,如下所示: is_comb_sum_equal_10(Numbers,_,5): - combination(5,Numbers,C),totals_10(C,0),first_to_last(C)。 它会确保新条件在整个列表中的5个整数的当前组合上运行吗? – Amy 2009-12-13 16:38:00