algorithm - pisinger对subsetsum算法的修改

标签 algorithm complexity-theory np

我正在查看 pisinger 的算法,详见此处

Fast solution to Subset sum algorithm by Pisinger

在维基百科上http://en.wikipedia.org/wiki/Subset_sum_problem

For the case that each xi is positive and bounded by a fixed constant C, Pisinger found a linear time algorithm having time complexity O(NC).[3] (Note that this is for the version of the problem where the target sum is not necessarily zero, otherwise the problem would be trivial.)

他的方法似乎有两个限制。第一个特别指出任何输入中的所有值都必须是 <= C .

在我看来,仅凭该约束,这不是可以解决原始子集和问题(没有限制)的算法。

但是假设C=1000000例如。然后在我们甚至在输入列表上运行算法之前。我们不能只将每个元素除以某个数字 d (也将目标总和除以 d)这样输入列表中的每个数字都是 <= C . 当算法返回某个子集时 s , 我们只是将 s 中的每个元素相乘通过 d .我们将拥有真正的子集。

有了这个观察,感觉我们需要那个 C 似乎不值得一提。约束。或者至少说输入可以更改 W.L.O.G(不失一般性)。所以无论输入如何,我们仍然可以解决同样的问题。换句话说,这种限制并没有使问题变得更难。所以实际上他的算法唯一的限制是它只能处理数字 >=0 .

我说得对吗?

谢谢

最佳答案

adrian.budau 说的是正确的。

在多项式解中, 在你说的除法之后,数组的每个值都应该保持为整数。 否则 DP 解决方案不再有效,因为项目值用作 DP 数组中的索引。

以下是我对子集和问题 (C=ELEMENT_MAX_VALUE) 的多项式 (DP) 解决方案

bool subsetsum_dp(VI& v, int sum)
{
    const int MAX_ELEMENT = 100;
    const int MAX_ELEMENT_VALUE = 1000;
    static int dp[MAX_ELEMENT+1][MAX_ELEMENT*MAX_ELEMENT_VALUE + 1]; memset(dp, -1, sizeof(dp));

    int n = S(v);
    dp[0][0] = 1, dp[0][v[0]] = 1;//include, excluse the value
    FOR(i, 1, n)
    {
        REP(j, MAX_ELEMENT*MAX_ELEMENT_VALUE + 1)
        {
            if (dp[i-1][j] != -1) dp[i][j] = 1, dp[i][j + v[i]] = 1;//include, excluse the value
        }
    } 
    if (dp[n-1][sum] == 1) return true;
    return false;
}

关于algorithm - pisinger对subsetsum算法的修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24473707/

相关文章:

python:os.path.exists 的复杂性存在于 ext4 文件系统中?

hashtable - 使用巨大的哈希表在多项式时间内解决数独

algorithm - 运输约束和存储水平的优化算法来解决CLSP(容量划分)

c - 当我们为 50n logn 计算 Big-Oh 时,它是 O(n log n)?我们可以把 O(n^5) 当作 Big-Oh 吗?

algorithm - 为什么回溯在运行时间上是线性的?

algorithm - 了解 “before” 在编程任务中的使用

python - 使用随机数列表和所有简单的数学运算符计算所有可能的组合以达到给定目标

数据库与纯文本

algorithm - 这段代码的时间复杂度是多少? (log3n)

python - 用另一列中重复值的数量填充一列