为什么不采用数值算法中数字的一元表示形式呢?


15

伪多项式时间算法是对输入值(幅度)具有多项式运行时间,而对输入大小(位数)具有指数运行时间的算法。

例如,测试数字是否为质数,需要循环从2到数字,并检查 mod是否为零。如果mod花费O(1)时间,则总时间复杂度将为O(n)。n - 1 n inn1n i

但是,如果让为写入输入所需的位数,则(二进制),因此,问题的运行时间将是指数的O()。x = 日志n n = 2 x 2 xxx=lognn=2x2x

我的问题是,如果我们考虑输入的一元表示形式,则始终为,则伪多项式时间将等于多项式时间复杂度。那么为什么我们从不这样做呢?x = nnx=n

此外,由于存在背包的伪多项式时间算法,因此通过取,背包将成为多项式,结果P = NPx=n


3
实际上,我们很少这样做。出于同样的原因,我们通常不使用一元语言,但是与这些野兽有关的结果很多。你调查了吗?
安德烈·索萨莱莫斯

2
是的,如果消除大小和大小之间的差异,则会丢失所有基于该差异的概念。
安德烈·索萨莱莫斯

7
因为这使恶魔穿上了漂亮的衣服。它不会使任何事情变得更快,只会使“运行时间复杂性”变得毫无意义。
拉斐尔

4
@Drupalist实际上,一元背包问题实际上不知道是NP完全的,因为对背包问题的正常归纳假设数字是以二进制形式写的。如果您尝试执行标准归约法,但是将数字写成一元,则无法以多项式时间计算归约法。结果,一元背包问题在多项式时间内可以解决,但这并不意味着P = NP。
templatetypedef

2
您可能需要检查其他标记为伪多项式的答案,尤其是这个答案。
拉斐尔

Answers:


17

这意味着一元背包在P中。这​​并不意味着背包(具有二进制编码的数字)在P中。

背包已知是NP完整的。如果您显示背包在P中,则表明P = NP。

但是您尚未显示背包在P中。您已经证明一元背包在P中。但是,一元背包并不知道是NP完整的(实际上,标准的怀疑是它很可能不是NP完整的)。因此,将一元背包放在P中并不意味着P = NP。


那么,我们应该更关心哪个问题,背包还是一元背包?如果您的动机是基于实际的考虑,那么答案将取决于您要解决背包问题的数量:如果数量很大,那么与单价背包相比,您当然更关心背包。如果您的动机是基于理论上的考虑,那么背包可以说是更有趣,因为它使我们可以更深入地了解-可以使我们区分大小与大小-而一元背包可以阻止我们进行区分。


要回答有关背包问题的动态编程算法的后续问题:

是的,相同的动态编程算法可以应用于背包,可以应用于一元背包。它的运行时间是数字量级的多项式,但是当以二进制编码时,其运行时间是数字长度的指数(不是多项式)。因此,当输入以一元编码时,其运行时间输入长度的多项式,而当输入以二进制编码时,其运行时间不是输入长度的多项式。这就是为什么我们确实将此动态规划算法视为一元背包的多项式时间算法,而不是将其视为(二进制编码)背包的多项式时间算法的原因。

回想一下,如果算法的运行时间最多为输入长度(以位为单位)的多项式,那么我们说算法以多项式时间运行。


1
非常感谢,我不知道同一算法的一元和非一元的复杂度类别可能不同。为什么标准背包的动态编程解决方案不能应用于一元背包,而导致了不同的复杂性呢?我在理解问题的一元版本时遇到问题。
妈妈D

@Drupalist,我已经编辑了答案,在结尾处添加了两个段落来回答该问题。
DW

非常感谢,据我了解,输入大小及其大小之间的差异是多项式与伪多项式之间区别的原因,我使用一元表示法试图消除这种差异,如果我们忘记了背包并回到数值算法,我想知道通过设置多项式和伪多项式的解释是什么?再次感谢x=n
妈妈D

@Drupalist,我不确定通过设置表示什么,所以我不确定如何回答。在这一点上,我建议最好提出一个新的(独立的)问题(并在该问题中定义所有变量)。这个平台不太适合跟进或反复提问:我们必须处理的最佳方法是根据您从该问题的答案中学到的知识来提出一个新问题。x=n
DW

1
@NikosM。,好的,知道了。感谢您的反馈。就我个人而言,我不认为该陈述是错误的,因此我将其保留原样。(我的推理:输入的长度确实取决于表示形式的选择,因此我不认为它与您所写的内容相抵触。)但是,我的观点很可能太狭窄,或者更详细的解释或不同的观点可能会增加价值。如果您觉得这点可能更清楚,请随时写其他答案或提出修改建议。
DW

6

我会在DW的答案中添加一件事:

我见过一些人认为,因为一元背包位于P中,所以我们可以用它代替当前最佳算法具有指数时间的背包。

假设输入为和并考虑背包和一元背包的动态编程算法。两者的运行时间均为。这是相同的运行时间。即,如果您有输入,则对一元背包使用动态编程还是对背包使用动态编程都没有关系。他们两个都将花费(大约)相同的时间来解决问题实例。从理论上讲,在任何使用一个的地方都可以使用另一个。您只需要将数字从一元转换为二进制,反之亦然。W={w1,,wn}kO(nk)

那么,根据输入的大小来定义算法的复杂性又有什么意义呢?为什么不总是用参数呢?O(nk)

如果您孤立地关心问题,则可以这样做。实际上,算法领域的人们经常这样做。图算法的复杂性通常用顶点数和边数来表示,而不是用编码它们的字符串的大小来表示。

但这只是在我们处理一个孤立的问题时。当我们用不同种类的输入处理问题时,它没有用。对于图,我们可以讨论到顶点和边数的运行时间。对于背包,我们可以讨论物品的数量和背包的大小。但是,如果我们想同时谈论两者呢?例如,当我们想要减少问题之间的联系,或讨论包括任意问题的问题类别,而不仅仅是以图形为输入的问题时。我们需要输入的通用参数。一般而言,输入只是一个字符串,是我们将其符号解释为一元数,二进制数,图等的方法。要发展算法复杂性和问题的一般理论,我们需要输入的一般参数。输入的大小是一个显而易见的选择,事实证明它足够健壮,因此我们可以在此之上构建合理的理论。这不是唯一的可能性。对于人为的人,我们可以建立基于2为输入的大小。它将正常工作。

现在,我们决定使用大小作为输入的通用参数,它迫使我们考虑使用字符串来编码对象。有多种编码方式,它们可以具有不同的大小。(它们也使不同的事情变得容易/困难。)根据算法的一般理论,无论我们将输入数字编码为一进制还是二进制都变得很重要。如果我们使用一元数,并且的大小为则最大数将为。如果我们使用的是二进制它可以大到。因此,当我们谈论解决背包问题的运行时间时,的大小k100100k21001k如果为100,则有两种截然不同的情况:一种情况下,我们只关心最多为100的输入。另一种情况下,我们关心的是最大为。k21001

假设我想看看是否可以在多项式时间内将SAT简化为背包。假设SAT的输入公式的大小为。然后,我将只能为Knapsack构建一个输入,该输入在具有多项式大小。假设是我构建的背包输入的大小。如果我使用一元,我只能将设为。如果使用二进制,则可以将设置为。事实证明,我需要将放得很大,才能将SAT的背包降低。因此,一元背包将无法将SAT降低到它。二进制背包将起作用。我们将能够创建一个更大的Knapsack实例nnp(n)kp(n)k2p(n)1kk 如果我们使用二进制。

考虑这种情况的另一种方法:假设您有一个黑色的盒子可以解决一元背包,另一个可以解决背包。假设您有时间为黑盒编写一个位输入。黑匣子中哪个更强大?显然,它使用二进制编码。我们可以使用它来解决与一元背包黑匣子可以解决的问题相比呈指数增长的背包问题。ķnk


非常感谢您,再一个问题,将输入转换为一进制表示,确定数字是否为质数的问题将如何处理?这个问题是基于输入幅度的多项式,但是基于输入位数(如我在问题中指出的)是指数的,这种转换会更好吗?
M ama D

nO(n)nb=210241210241210241
卡夫

很好的澄清,不过请看我在DW的回答下的与此帖子相关的评论
Nikos M.

2

简而言之,我将向您展示原因。

Tally

x = input integer

factors = [];

for i in range(1, x + 1):
    if x % i == 0:
     factors.append(i)

 print(factors)

xxO(2n)

Tally/UnaryO(n)x

x = input tallies

factors = [];

for i in range(1, x + 1):
    if x % i == 0:
     factors.append(i)

 print(factors)

输入表示形式不会使代码运行更快。即使第二种算法是真正的倍增时间。在发现RSA的因素方面不是很实际。


很好的例子,谢谢
M ama D
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.