【问题标题】:Linear algorithm to find minimum subset sum over a threshold找到阈值上的最小子集和的线性算法
【发布时间】:2013-06-18 02:51:04
【问题描述】:

我有一个 N 个正整数的集合,每个正整数都以一个(相对较小的)常数 C 为界。我想找到这些数字的一个子集,其中最小的总和大于(或等于)一个值 K。

涉及的数字不是很大(

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

但是,我对算法的理解不够好,无法自己执行此操作。事实上,我什至不确定它所基于的假设是否仍然成立......

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

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

-谁能提供伪代码或详细解释?

谢谢。

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

(如果措辞/格式不正确/等,我深表歉意。我还是 StackOverflow 的新手...)

【问题讨论】:

  • 这不是背包问题的变种吗?
  • 是的。具体来说,是 Subset-Sum 的一种变体(它本身就是一个特殊的背包)。
  • 为了将来参考,如果有重复,请尽量避免使用术语“set”。 “收藏”是一个更好的词。

标签: c++ algorithm subset-sum


【解决方案1】:

Pisinger 算法为您提供小于或等于背包容量的最大总和。要解决您的问题,请使用 Pisinger 找出要放入子集中的不。形式上,设项目为 w_1, ..., w_n,最小值为 K。将 w_1, ..., w_n 和 w_1 + ... + w_n - K 给 Pisinger,然后取 Pisinger 没有的所有项目。

【讨论】:

  • 我确实考虑过进行逆运算,正如你所说,但它是 O(n(n-k)) = O(n^2),不是线性的。
  • @Athena Pisinger的运行时间是O(item count * max item),它不依赖于背包大小或最优解存储的物品数量。
  • 啊,你是对的! (我把我的常数弄混了。)这将适用于我的目的。非常感谢!
【解决方案2】:

一种解决方案是:

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 bound),所以运行时间是O(N^2),空间是O(N)。您可以使用长度为 NC 的位数组作为 T 的后备存储。

【讨论】:

  • 我不认为 O(N^2) 算法算线性。
  • 哦,我没注意到标题,我以为我们只是在尝试多项式时间。
  • 我会澄清这个问题,说“线性”。无论如何,谢谢。
猜你喜欢
  • 2018-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
相关资源
最近更新 更多