我们如何假设对数字的基本运算需要固定的时间?


73

通常,在算法中,我们不关心数字的比较,加法或减法-我们假设它们在时间。例如,当我们说基于比较的排序是时,我们就假设了这一点,但是当数字太大而无法放入寄存器时,我们通常将它们表示为数组,因此基本操作需要为每个元素进行额外的计算。O n log n O(1)O(nlogn)

是否有证据表明可以在完成两个数字(或其他原始算术函数)的比较?如果不是,为什么我们说基于比较的排序是?O n log n O(1)O(nlogn)


我遇到这个问题时,我回答了一个SO问题,我意识到,我的算法是不,因为我迟早要处理大INT,也是它不是伪多项式算法,它是。PO(n)P


3
如果要计算比较数字的复杂度,则还应该根据输入的位大小写复杂度界限。因此,给定位数字,输入的位大小为,可以在时间内进行排序。w n = N w O N w log N = O n log n N wn=NwO(NwlogN)=O(nlogn)
2013年

2
复杂性研究基本上有两个“领域”或“制度”。通常,对于“固定宽度”操作假定操作,这对于大多数具有固定宽度数字表示形式(包括2-4个字节)的计算机语言来说是一个合理的近似值(例如,参见IEEE标准)。然后是“任意精度算术”,其中数字具有任意大小,并且对操作的复杂性进行了更为仔细/精确的研究。前者在应用分析中更多,后者在理论/抽象分析中更多。O(1)
vzn

Answers:


75

对于像我这样的以算法为生的人来说,21世纪的计算标准模型是整数RAM。该模型旨在比图灵机模型更准确地反映真实计算机的行为。现实世界中的计算机使用并行硬件在恒定时间内处理多位整数。也不是任意整数,而是(因为字长会随时间稳定增长)也不是固定大小的整数。

模型取决于单个参数,称为单词大小。每个内存地址都包含一个w位整数或word。在此模型中,输入大小n是输入中的单词数,算法的运行时间是对单词进行操作的次数。根据定义,对单词的标准算术运算(加法,减法,乘法,整数除法,余数,比较)和布尔运算(按位和,或xor,移位,旋转)需要O 1 时间。wwnO(1)

正式地,为了分析该模型中的算法,字长不是常数w。为了使模型与直觉一致,我们需要,否则我们甚至不能存储整数ñ一个字。但是,对于大多数非数值算法,运行时间实际上与w无关,因为这些算法并不关心其输入的基础二进制表示形式。Mergesort和heapsort都在O n log n 时间中运行;3个快速中位数在O n 2wlog2nnwO(nlogn)时间在最坏的情况下。一个值得注意的例外是二进制基数排序,它以 O n w 时间运行。O(n2)O(nw)

设置得到传统的对数成本RAM模型。但是一些整数RAM算法是为更大的字长而设计的,例如Andersson等人的线性时间整数排序算法,这需要瓦特= Ω 登录2 + ε Ñ w=Θ(logn)w=Ω(log2+εn)

对于实践中出现的许多算法而言,字长根本不是问题,我们可以(并且愿意)依靠更为简单的均成本RAM模型。唯一的严重困难来自嵌套的乘法,它可以用于构建非常大的整数非常快。如果我们可以在恒定时间内对任意整数执行算术运算,则可以在多项式时间内解决PSPACE中的任何问题w

更新:我还应该提到“标准模型”的例外,例如使用多带图灵机(或等效地,称为“位RAM”)的Fürer整数乘法算法和大多数几何算法(在理论上进行了分析)干净但理想化的“真实RAM”模型

是的,这是一罐蠕虫。


3
我知道我只是应该投票,但不能阻止自己说出来:这是最好的答案。诀窍在于:(1)算术运算从定义上讲是恒定时间,这是可以的,因为从理论上讲您可以选择任何模型,并且(2)您应该有选择某些模型的一些理由,而这个答案解释了它们的含义。
rgrig 2012年

我同意rgig((我也应该投票)),但是一个小问题是输入大小与输入数字无关,例如,如果输入我的最大数字是m,如果选择计算模型,如我所愿,这导致伪多项式时间算法变为P,对吗?nmP

1
如果您的输入包含位数超过位的数字,则要拟合模型,您必须像现实生活中那样将它们拆分为w位的块。例如,如果您的输入由0M之间的N个整数组成,则您的真实输入大小为N log w M = N lg M /lg w 。因此,当M大时,像O N M 时间这样的伪多项式运行时间在输入大小上仍然是指数的。wwN0MNlogwM=(NlgM)/(lgw)O(NM)M
JeffE

在Real RAM模型中是否分析了不是秘密的“订单类型RAM”算法的算法?我从来没有考虑过太多,但是不能很快提出一个没有的例子。
2012年

1
@Louis:是,大量的:Voronoi图,欧几里德最短路径,递归插条,单纯分区树,....但是,最好的例子是高斯消去法,其中在运行对实体模型RAM时间(或单位成本的整数RAM,但在整数RAM上需要O n 4时间O(n3)O(n4)
JeffE 2012年

24

这仅取决于上下文。在处理算法的比特级复杂性时,我们并不是说两个位数字的和是O 1 ,而是说是O n 乘法等类似nO(1)O(n)


从您引用的文章中可以得出:“可以用两种不同的方法进行测量:一种是根据要测试或乘以的整数来表示,另一种是按照这些整数中的二进制位数(位数)来衡量”,但事实并非如此,我们应始终根据输入的大小进行度量。

1
@SaeedAmiri:它仅取决于所使用的编码。在文章中,例如,如果输入是一个整数指定使用一元编码,试除法将需要仅θ Ñ 1 / 2。这是输入大小的多项式!这是否意味着按除法进行的分解在P中?不,该算法是伪多项式。使用通用的二进制编码,您将得到一个与输入大小相同的指数算法。如上所述,这是因为输入n中的位数改变了它的编码而呈指数地变小了。nθ(n1/2)Pn
Massimo Cafaro

顺便说一句,如果伪多项式算法的参数在实际情况下的数量级相当低,则实际上可能有用。最著名的例子可能是解决背包问题的伪多项式算法。
马西莫卡法罗

首先,我应该提到您所引用的Wiki页面不好,因为它没有任何良好的引用;另外,我也不知道您为什么认为我在谈论伪多项式时间算法,可能是因为输入大小通常很笨拙在这种情况下?但我不是在谈论它们,我主要是在谈论问题,即使是假设输入大小也是如此,例如排序,因为我们不能作弊并说NPC问题在P中,我认为我们不应该这样做说排序是O n log n ),除了我们有形式证明可以忽略比较。PPO(nlogn)

我正在讨论伪多项式算法,以将您的注意力集中在输入的大小上,以表明它可能会引起误解。这是另一个例子。您将得到一个自然数作为输入,即,并且该算法运行一个循环,在该循环中,它会进行O 1 次时间运算,进行n次迭代。根据输入大小来衡量的这种简单循环算法的复杂度为O n = O 2 l g n。由于l g nnO(1)nO(n)=O(2lgn)lgn是输入大小,算法是输入大小的指数!考虑一下。现在,您可能会理解“仅取决于上下文”的含义。
马西莫卡法罗

16

为了回答上述问题:算法学家经常通过使用RAM模型来做到这一点。对于排序,在很多情况下,人们甚至分析了比较简单的比较模型,我在链接的答案中对此进行了更多讨论。

要回答关于它们为什么这样做的隐性问题:我想说,对于某些类型的组合算法,该模型具有相当好的预测能力,其中组合的数字都是“小”,并且在实际机器上适合寄存器。

要回答关于数值算法的隐式后续操作:不,这里的普通RAM模型不是标准。即使是高斯消除也需要一些注意。通常,对于排名计算,Schwartz Lemma将进入(例如,此处的第5节)。另一个典型的例子是椭球算法,这需要分析一些护理分析。

最后:人们甚至在最近就考虑过字符串排序

更新:这个问题的问题在于“ we”和“ assess”没有那么精确地指定。我要说的是,在RAM模型中工作的人们并不是在进行数值算法或复杂性理论(确定除法的复杂性是一个著名的结果)。


嗯,看来这是一个有趣的答案...

是否有原因不能完全回答问题?
路易(Louis)

7

O(1)O(1)

python -mtimeit "$a * $b"$a10{1,2,...,66}$b = 2*$a

1050log10(sys.maxint)


O(n)O(nlognlogm)

7

O(1)

O(logM)O(NlogN)O(NlogNlogM)

M


O(logm)O(logn)m

O(logN)

nnnn

您说得对,我更正了我的回答。
Erel Segal-Halevi

4

我会说我们通常假设O(1)算术运算,因为我们通常在32位整数或64位整数或IEEE 754浮点数的上下文中进行操作。O(1)可能是这种算法的一个很好的近似值。

但是总的来说,这是不正确的。通常,您需要一种算法来执行加法,减法,乘法和除法。Boolos,Burgess和Jefferies的“ 可计算性和逻辑”作为一种方式来理解,至少在我的第4版副本中,它是通过几个不同的形式系统,递归函数和Abacus机器来理解这一点的。

您可以查看使用教堂数字进行减法和除法的lambda微积分术语,以轻松了解为什么这两个运算不是O(1)。对于加法,乘法和乘幂运算很难看到,但是如果您考虑教堂数字本身的形式,那就在那里。

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.