我会在DW的答案中添加一件事:
我见过一些人认为,因为一元背包位于P中,所以我们可以用它代替当前最佳算法具有指数时间的背包。
假设输入为和并考虑背包和一元背包的动态编程算法。两者的运行时间均为。这是相同的运行时间。即,如果您有输入,则对一元背包使用动态编程还是对背包使用动态编程都没有关系。他们两个都将花费(大约)相同的时间来解决问题实例。从理论上讲,在任何使用一个的地方都可以使用另一个。您只需要将数字从一元转换为二进制,反之亦然。W={w1,…,wn}kO(nk)
那么,根据输入的大小来定义算法的复杂性又有什么意义呢?为什么不总是用参数呢?O(nk)
如果您孤立地关心问题,则可以这样做。实际上,算法领域的人们经常这样做。图算法的复杂性通常用顶点数和边数来表示,而不是用编码它们的字符串的大小来表示。
但这只是在我们处理一个孤立的问题时。当我们用不同种类的输入处理问题时,它没有用。对于图,我们可以讨论到顶点和边数的运行时间。对于背包,我们可以讨论物品的数量和背包的大小。但是,如果我们想同时谈论两者呢?例如,当我们想要减少问题之间的联系,或讨论包括任意问题的问题类别,而不仅仅是以图形为输入的问题时。我们需要输入的通用参数。一般而言,输入只是一个字符串,是我们将其符号解释为一元数,二进制数,图等的方法。要发展算法复杂性和问题的一般理论,我们需要输入的一般参数。输入的大小是一个显而易见的选择,事实证明它足够健壮,因此我们可以在此之上构建合理的理论。这不是唯一的可能性。对于人为的人,我们可以建立基于2为输入的大小。它将正常工作。
现在,我们决定使用大小作为输入的通用参数,它迫使我们考虑使用字符串来编码对象。有多种编码方式,它们可以具有不同的大小。(它们也使不同的事情变得容易/困难。)根据算法的一般理论,无论我们将输入数字编码为一进制还是二进制都变得很重要。如果我们使用一元数,并且的大小为则最大数将为。如果我们使用的是二进制它可以大到。因此,当我们谈论解决背包问题的运行时间时,的大小k100100k2100−1k如果为100,则有两种截然不同的情况:一种情况下,我们只关心最多为100的输入。另一种情况下,我们关心的是最大为。k2100−1
假设我想看看是否可以在多项式时间内将SAT简化为背包。假设SAT的输入公式的大小为。然后,我将只能为Knapsack构建一个输入,该输入在具有多项式大小。假设是我构建的背包输入的大小。如果我使用一元,我只能将设为。如果使用二进制,则可以将设置为。事实证明,我需要将放得很大,才能将SAT的背包降低。因此,一元背包将无法将SAT降低到它。二进制背包将起作用。我们将能够创建一个更大的Knapsack实例nnp(n)kp(n)k2p(n)−1kk
如果我们使用二进制。
考虑这种情况的另一种方法:假设您有一个黑色的盒子可以解决一元背包,另一个可以解决背包。假设您有时间为黑盒编写一个位输入。黑匣子中哪个更强大?显然,它使用二进制编码。我们可以使用它来解决与一元背包黑匣子可以解决的问题相比呈指数增长的背包问题。ķnk