我有多组数据,比如
第1组2,3,5,10,15
Group2 4,6,23,15,12
第3组23,34,12,1,5
我需要来自这3组的最佳总和(例如总和(g1 + g2 + g3)< = 25)
1st(g1)5 +(g2)15 +(g3)+ 5 = 25(最佳组合)
现在,对于下一组合,不需要使用每个相应组的上述值
Group1 2,3, 5 ,10,15
Group2 4,6,23, 15 ,12
Group3 23,34,12,1, 5
第二(g1)2 +(g2)23 = 25(最佳组合)
Group1 2 ,3, 5 ,10,15
Group2 4,6, 23 , 15 ,12
Group3 23,34,12,1, 5
第3(g1)15 +(g2)6 +(g3)+ 1 = 22(最佳组合)
我希望这可能有点复杂。但我可能会更好地解决这个问题。
由于
答案 0 :(得分:4)
这是NP-Hard问题。
sub-set sum减少了
子集和问题:给定多集S
和数k
:当且仅当S'
的{{1}}的子集时才返回true 1}},总结为S
。
<强>减少强>
给定k
形式的子集和问题的实例,在(S,k)
形式创建此问题的实例,其中(G1,G2,...,Gn,k)
是具有元素{{的单例组1}}来自Gi
,i
是我们正在寻找的数字。
<强>证明:强>
子集和 - &gt;这个问题:假设有S
个子集k
,那么通过选择每个组中的一个元素:S'={si_1,si_2,...,si_m}
,它们总和为k,因为每个{ {1}}仅包含元素si_1 + si_2 + ... + si_m = k
。
此问题 - &gt;子集和:这里有相同的想法,假设有一组单例组总和为Gi_1, Gi_2, ... , Gi_m
,我们可以找出Gi
中哪些元素需要得到所需的子集和si
。
<强>结论:强>
这个问题是NP-Hard,并且没有已知的多项式解。由于您所寻求的是NP-Hard问题的优化问题,因此您的优化问题也是NP-Hard。因此,获得最佳解决方案的最佳方法可能是指数级解决方案,例如蛮力:只检查所有可能性,并返回最佳匹配。
注意:强>
编辑:指数解决方案示例[伪代码]:
注意它没有经过测试,但它背后的想法应该有效:只检查第一组的所有可能性,并递归k
减少一组,所以最后 - 你耗尽所有可能的解决方案,并且从他们那里回报最好的。
S
答案 1 :(得分:0)
子集和问题具有伪多项式动态编程方法。我们可以将其映射到具有复杂度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]