查找列表中总和为某个值的所有元素组合

时间:2018-03-15 11:05:53

标签: prolog

假设我有一个随机长度列表,例如:

L = [190, 20, 80, 200, 10].

有没有办法在输出列表中获取所有可能的元素组合,以使它们的总和小于或等于给定值?

E.g。 find_elements(MaxValue,InputList,OutputList)。

MaxValue = 200的可能解决方案:

OutputList = [190, 10]
OutputList = [200]
OuputList = [20, 80, 10]

到目前为止,我的代码看起来像这样:

solutions(_, [], [], _).

solutions(MaxValue, [H|T], OutputList, Acc):-
    Z is H + Acc,
    Z > MaxValue,
    solutions(MaxValue, T, OutputList, Acc), !.

solutions(MaxValue, [H|T], [H|T2], Acc):-
    Z is H + Acc,
    Z =< MaxValue,
    solutions(MaxValue, T, T2, Z).

solutions(MaxValue, Inputlist, OutputList):-
    solutions(MaxValue, Inputlist, OutputList, 0).

如果我打电话 solutions(200, [190, 250, 3, 4, 180, 10], X) 我明白了:

X = [190, 3, 4]

X = [3, 4, 180]也是如此,X = [180, 10]也是如此。我希望将它们全部作为解决方案。

提前致谢!

1 个答案:

答案 0 :(得分:1)

快速实施可能是这样的:

subset([], []).
subset([H|T], [H|T1]):-
  subset(T,T1).
subset([_|T],T1):-
  subset(T, T1).

solve(MaxVal,Lin,Lout):-
    subset(Lin,Lout),
    sumlist(Lout,Val),
    Val < MaxVal.

查询:

?- solve(200,[190, 20, 80, 200, 10],L).
L = [190]
L = [20, 80, 10]
L = [20, 80]
L = [20, 10]
L = [20]
L = [80, 10]
L = [80]
L = [10]
L = []

因此,您可以找到所有子集,然后检查列表总和是否小于值MaxVal