我知道这Knapsack
是NP完全的,而DP可以解决。他们说DP解决方案是pseudo-polynomial
,因为它在“输入长度”(即对输入进行编码所需的位数)中呈指数形式。不幸的是我没有得到。有人可以pseudo-polynomial
慢慢向我解释那件事吗?
Answers:
对于具有N个项目且尺寸为W的背包的无界背包问题,运行时间为O(NW)。W在输入长度上不是多项式,这就是伪多项式的原因。
考虑W = 1,000,000,000,000。它仅用40位来表示该数字,因此输入大小= 40,但是计算运行时使用的因子为1,000,000,000,000,即O(2 40)。
因此,运行时间更准确地说是O(N.2 W),它是指数。
另请参阅:
在大多数问题中,我们要处理大量的数字,这些数字很适合标准的int / float数据类型。由于大多数处理器的构建方式是一次可处理4-8个字节的数字而无需支付额外的费用(相对于无法容纳的数字,例如1个字节),我们很少会遇到因将数字放大或缩小而导致运行时间发生变化的情况。在实际问题中遇到的范围之内-因此,主要因素仍然只是大量的数据点,即我们习惯的n或m个因素。
(您可以想象到Big-O表示法隐藏了一个常数因子,该常数因子将每个数据分割32或64位,只要我们的每个数字都适合那么多或更少的位数,就仅保留数据点数)
但是,请尝试与其他算法配合使用,以处理涉及大整数的数据集-需要大于8个字节表示的数字-并查看对运行时有何影响。即使在诸如二进制排序之类的其他算法中,涉及到的数字的大小也总是有所不同,一旦您扩展到安全缓冲区之外,常规处理器就会通过处理4-8个字节的批处理为我们提供“免费”服务。
我们讨论过的Knapsack算法的窍门是,它对特定参数W的大小异常敏感(相对于其他算法)。向W加一位,您的算法运行时间就会增加一倍。在此之前,我们还没有见过其他算法对价值变化产生如此戏剧性的反应,这就是为什么我们似乎对Knapsack的处理方式有所不同的原因-但这是对它以非多项式方式响应的真实分析。输入大小的变化。
背包算法的运行时间不仅受输入大小(n-项目数)的限制,还受输入大小(W-背包容量)O(nW)的限制,O(nW)的大小呈指数关系。在计算机中以二进制(2 ^ n)表示。计算复杂性(即,如何通过位在计算机内部进行处理)仅与输入的大小有关,而与它们的大小/值无关。
暂时忽略值/重量列表。假设我们有一个背包容量为2的实例。W将在输入数据中占用两位。现在,我们将背包容量增加到4,保留其余输入。我们的输入仅增加了一点,但是计算复杂度却增加了两倍。如果将容量增加到1024,则W的输入将只有10位,而不是2位,但是复杂度增加了512倍。时间复杂度以二进制(或十进制)表示的W大小呈指数增长。 。
另一个帮助我理解伪多项式概念的简单示例是朴素素性测试算法。对于给定的数字n,我们正在检查是否将其均匀除以范围2..√n中的每个整数,因此算法采用√(n-1)步。但是在这里,n是输入的大小,而不是大小。
Now The regular O(n) case
相反,在数组中搜索给定元素的时间为多项式时间:O(n)。它最多需要n步,这里n是输入的大小(数组的长度)。
[ 看这里 ]
我的理解是,如果容量输入是[1,2,...,W]数组,其大小为W ,则容量将为O(W)。但是容量输入不是一个数字数组,它是一个整数。时间复杂度大约是关系到尺寸输入。整数的大小不是整数的值,而是表示整数的位数。我们稍后在算法中将这个整数W转换为数组[1,2,...,W],导致人们误认为W是大小,但是这个数组不是输入,整数本身就是。
将输入视为“一组东西”,将大小视为“该阵列中有多少东西”。项输入实际上是数组中n个项的数组,因此size = n。容量输入不是其中的W数字数组,而是一个由log(W)位数组表示的单个整数。将它的大小增加1(加上1个有意义的位),W增加一倍,运行时间增加一倍,因此,指数时间复杂度增加。