我有一个N个正整数的集合,每个正整数由一个(相对较小的)常数C限定。我想找到这些数的一个子集,其最小和大于(或等于)一个值K。
所涉及的数字并不是非常大(<100),但即使在最坏的情况下我也需要良好的表现。我想也许我可以将Pisinger的动态编程算法应用到任务中;它在O(NC)时间运行,我碰巧满足有界正数的要求。
[编辑]:数字未排序,可能有重复数据。
但是,我自己并不了解这个算法。事实上,我甚至不确定它所基于的假设是否仍然存在......
- 是否可以根据我的需要调整此算法?
- 或者我可以使用另一种同样有效的线性算法吗?
- 有人提供伪代码或详细解释吗?
感谢。
链接到我正在调查的Subset-Sum代码: Fast solution to Subset sum algorithm by Pisinger
(道歉,如果措辞不当/格式化等等。我还是StackOverflow的新手......)
答案 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的后备存储。