(在您回复其他SO问题的链接或将其作为副本关闭之前,请仔细阅读此问题。这与此问题的标准变体不同,我搜索了很长时间,所以我很漂亮确定这里没有这样的问题)
我需要找出最小可能S 是否是> = T 子集X [i] 的总和>(某个目标值,小于全套的总和)。
该集合不是很大(大约40个元素),但对于指数回溯解决方案来说仍然太大。
数字和总和是巨大的(大约10 ^ 15),因此动态编程将无法工作(可能状态的数量很大,因此memoization表很快会耗尽内存)
出于同样的原因,Pisinger的线性时间算法不起作用(它是O(nr),其中r是总和的上限,在这种情况下太大了)。
是否有一些确定性算法可以帮助我在这种大数目但数量很少的情况下?我不想采用一些近似算法。
答案 0 :(得分:2)
鉴于上述条件,我认为使用branch & bound的回溯解决方案是您获得确切解决方案的最佳选择。
我们的想法是检查所有子集,但您可以在算法运行期间修剪一些可能子集的计算树。
例如,假设您正在寻找S = 10^8
,并且您已找到sol=10^8 + 10^7
的解决方案,现在,您正在检查所有子集,这些子集是某些X
的超集,而您找出sum(X) = 10^9
。无需继续检查包含X
的任何子集,您可以跳过它们 - 它们不会让您达到最佳状态。
我也尝试并行化解决方案,分支和绑定通常很容易并行化,只需要偶尔同步新的最佳解决方案。
答案 1 :(得分:1)
正如你所说的那套不是很大(大约40)。我认为复杂度O(2^(n/2) n)
的经典指数时间算法将符合您的需求http://en.wikipedia.org/wiki/Subset_sum_problem#Exponential_time_algorithm。
我可以在这里简要介绍一下这种方法。将集合拆分为两个相等的大小集合,例如A和B.并枚举它们的子集和以生成两组大小2^(n/2)
,例如PA和PB。然后,您可以对PA和PB进行排序,并使用二进制搜索来查找超过T
及时O(2^(n/2) n)
的总和。