Задача суммы подмножества имеет подход псевдополиномиального динамического программирования. Мы можем сопоставить ее с этой проблемой вариации со сложностью O(S*N)
и O(S)
пробел, где S
- максимальная сумма (25 в вашем примере), а N
- общее количество элементов во всех группах.
Эта сложность не зависит от общего количества групп, поэтому лучше подходит, если O(N^G)
решение с использованием грубой силы не будет сходиться для высоких значений G>=10
. Но обратите внимание, что этот алгоритм не будет работать для S>=biginteger
.
Короче говоря, рекурсивное решение DP выглядит следующим образом:
Sol(grp_i, S) = True if(grp_i==1 && grp_i dataset has element S) // base case
= True if(Sol(grp_i-1, S)==True OR
there exists element 'e' in grp_i dataset
such that Sol(grp_i-1, S-e)==True)
= False otherwise
Как только мы выясним, является ли набор данных разрешимым, мы можем вернуться к решению.
Программа Python ниже:
def bestsum(data, maxsum):
res = [0]*(maxsum+1)
res[0] = [] # base case
for group in data:
new_res = list(res) # copy res
for ele in group:
for i in range(maxsum-ele+1):
if res[i] != 0:
new_res[i+ele] = list(res[i])
new_res[i+ele].append(ele)
res = new_res
for i in range(maxsum, 0, -1):
if res[i] != 0:
return res[i]
break
return []
print bestsum( [[2,3,5,10,15], [4,6,23,15,12], [23,34,12,1,5]], 25)
print bestsum( [[2,3,10,15], [4,6,23,12], [23,34,12,1]], 25)
print bestsum( [[3,10,15], [4,6,12], [23,34,12,1]], 25)
Выход:
~$ python2 subsetsum.py
[5, 15, 5]
[2, 23]
[12, 12]