Given a list of values (e.g. 10, 15, 20, 30, 70), values N (e.g. 3) and S (e.g. 100), find a subset that satisfies :
- length of subset >= N
- sum of subset >= S
The sum of the subset should also be the least possible (the sum of remaining values should be the greatest possible) (e.g. result subset should be (10,20,70), not (15,20,70) which also satisfies 1. and 2.).
I was looking at some problems and solutions (Knapsack problem, Bin packing problem, …) but didn’t find them applicable. Similar problems on the internet were also not suitable for some reason (e.g. number of elements in subset was fixed).
Can someone point me in the right direction? Is there any other solution other than exhausting every possible combination?
Edit – working algorithm I implemented in ruby code, I guess it can be further optimized:
def find_subset_with_sum_and_length_threshold(vals, min_nr, min_sum)
sum_map = {}
vals.sort.each do |v|
sum_map.keys.sort.each do |k|
addends = sum_map[k] + [v]
if (addends.length >= min_nr && k+v >= min_sum)
return addends
else
sum_map[k+v] = addends
end
end
sum_map[v] = [v] if sum_map[v].nil?
end
end
This is not very different from the 0-1 knapsack problem.
Time complexity is O(L*N*S), where L is the length of the list, N and S are given limits.
Space complexity is O(L*N).
Time complexity is O(L*S), where L is the length of the list, S is given limit.
Space complexity is O(L*S).
Algorithm that also minimizes the subset size:
Time complexity is O(L*N*S), where L is the length of the list, N and S are given limits.
Space complexity is O(L*N*S).