线性算法,用于在阈值上找到最小子集和

时间:2013-06-18 02:51:05

标签: c++ algorithm subset-sum

我有一个N个正整数的集合,每个正整数由一个(相对较小的)常数C限定。我想找到这些数的一个子集,其最小和大于(或等于)一个值K。

所涉及的数字并不是非常大(<100),但即使在最坏的情况下我也需要良好的表现。我想也许我可以将Pisinger的动态编程算法应用到任务中;它在O(NC)时间运行,我碰巧满足有界正数的要求。

[编辑]:数字未排序,可能有重复数据。

但是,我自己并不了解这个算法。事实上,我甚至不确定它所基于的假设是否仍然存在......

- 是否可以根据我的需要调整此算法?

- 或者我可以使用另一种同样有效的线性算法吗?

- 有人提供伪代码或详细解释吗?

感谢。

链接到我正在调查的Subset-Sum代码: Fast solution to Subset sum algorithm by Pisinger

(道歉,如果措辞不当/格式化等等。我还是StackOverflow的新手......)

2 个答案:

答案 0 :(得分:2)

Pisinger算法为您提供小于或等于背包容量的最大总和。要解决您的问题,请使用Pisinger找出要放入子集的 not 。正式地,让项目为w_1,...,w_n,最小值为K.给予Pisinger w_1,...,w_n和w_1 + ... + w_n - K,然后取Pisinger没有的每个项目。< / p>

答案 1 :(得分:0)

一个解决方案是:

T = {0}

for x in V
   for t in T
       T.insert(x+t)

for i in K to max(T)
   if (T.contains(i))
       return i

fail

这为您提供了子集的大小,但您可以适应输出成员。

T的最大大小为O(N)(因为C绑定),因此运行时间为O(N ^ 2),空间为O(N)。您可以使用长度为NC的位数组作为T的后备存储。