我知道Knapsack
是NP完整的,而DP可以解决它。他们说DP解决方案是pseudo-polynomial
,因为它在“输入长度”(即编码输入所需的位数)中是指数的。不幸的是我没有得到它。任何人都可以慢慢向我解释pseudo-polynomial
事吗?
答案 0 :(得分:60)
对于具有N个项目和大小为W的背包的无界背包问题,运行时间为O(NW)。虽然输入的长度不是多项式,这使得伪 -polynomial。
考虑W = 1,000,000,000,000。它只需要40位来表示这个数字,因此输入大小= 40,但计算运行时使用因子1,000,000,000,000即O(2 40 )。
因此运行时更准确地说是O(W 中的N.2 位),这是指数的。
另见:
答案 1 :(得分:22)
在我们的大多数问题中,我们正在处理大量数字列表,这些数字符合标准的int / float数据类型。由于大多数处理器的构建方式一次只能处理4-8个字节的数字而无需额外成本(相对于数字而不是1英寸),我们很少会遇到从缩放数字或在实际问题中我们遇到的范围内 - 所以主导因素仍然只是数据点的数量,我们习惯的n或m因子。
(你可以想象Big-O表示法隐藏了一个常数因子,它将每个数据分成32或64位,只要每个数字都适合那么多,就只留下数据点数比特或更少)
但是尝试重新使用其他算法来处理涉及大整数的数据集 - 需要超过8个字节来表示的数字 - 并查看它对运行时的作用。所涉及的数字的大小总是有所不同,即使在其他算法如二进制排序中,一旦你扩展到安全缓冲区之外,传统处理器通过处理4-8字节批次给我们“免费”。
我们讨论的Knapsack算法的技巧是它对特定参数W的大小非常敏感(相对于其他算法)W。向W添加一位,并使算法的运行时间加倍。在此之前我们还没有看到对其他算法价值变化的那种戏剧性反应,这就是为什么看起来我们对待背包的方式不同 - 但这是对它如何以非多项式方式作出反应的真实分析改变输入大小。
答案 2 :(得分:8)
Knapsack算法的运行时间不仅取决于输入的大小(n - 项目数),还取决于输入的大小(W - 背包容量)O(nW),它是指数的它是如何在二进制计算机中表示的(2 ^ n)。计算复杂度(即如何通过位在计算机内完成处理)只关注输入的大小,而不是它们的幅度/值强>
暂时忽略价值/重量清单。假设我们有一个背包容量为2的实例.W将在输入数据中占用两位。现在我们将背包容量增加到4,保留其余的输入。我们的输入只增长了一点,但计算复杂性增加了两倍。如果我们将容量增加到1024,我们将只有10位输入用于W而不是2,但复杂性增加了512倍。时间复杂度以二进制(或十进制)表示的W大小呈指数增长
帮助我理解伪多项式概念的另一个简单例子是朴素素性测试算法。对于给定的数字n,我们检查它是否被范围2..√n中的每个整数数均分,因此该算法采用√(n-1)步。但在这里,n是输入的大小,而不是它的大小。
Now The regular O(n) case
相比之下,搜索给定元素的数组在多项式时间内运行:O(n)。它最多需要n步,这里n是输入的大小(数组的长度)。
[见这里]
答案 3 :(得分:2)
我理解这一点的方法是,如果容量输入是[1,2,...,W] 的数组,则容量将为O(W),大小为W.但容量输入不是数字数组,而是一个整数。时间复杂度与输入的大小的关系有关。整数的大小不是整数的值,而是表示它的位数。我们稍后将这个整数W转换成算法中的数组[1,2,...,W],导致人们错误地认为W是大小,但这个数组不是输入,整数本身就是。
将输入视为"一系列东西",大小为"数组中有多少东西"。项输入实际上是数组中n个项的数组,因此size = n。 容量输入不是W数字的数组,而是单个整数,由log(W)位数组表示。将它的大小增加1(增加1个有意义的位),W加倍,因此运行时间加倍,因此指数时间复杂度。
答案 4 :(得分:1)
复杂性基于输入。在背包问题中,输入是大小、最大容量和利润、重量数组。我们将 dp 表构造为 size * W 所以我们觉得它是多项式时间复杂度。但是,输入 W 是整数,不是数组。因此,它将是 O(size*(no Of bits required to store given W))。如果没有位增加 1,则运行时间加倍。因此它是指数的,因此是伪多项式。