Haskell中的整数时间复杂度

时间:2010-09-26 15:30:46

标签: haskell integer time-complexity

我上周在学校做了一项任务,实现了计算斐波纳契数列中第n个数的函数。 “子指派”是使用累积(可能不是正确的翻译)来实现它,以便给出函数O(n)时间复杂度。这一切都很好,直到我尝试制作函数(Int - > Integer)。通过实验,我意识到时间复杂度对于非常大的数字接近于O(n ^ 2)。 在我看来,这必须是因为Integer的实现,这使我对它的工作方式有点好奇。我做了一些谷歌搜索,没有找到任何看似有用的东西,所以我转向你们,希望得到解释或解释它的链接。

我的代码:

ackfib 0 = 0
ackfib 1 = 1        
ackfib n = loop n 1 0 1
    where
        loop n n1 n2 i 
            | i < n     = loop n (n1+n2) n1 (i+1)
            | i == n    = n1
            | i > n     = error "n must be greater than or equal to 0"

我感谢所有答案

2 个答案:

答案 0 :(得分:13)

这与Haskell无关,这只是Fibonacci数量迅速呈指数增长的结果。具体来说,第n个Fibonacci数具有大约(log 2 φ)n或大约0.48 n位,其中φ是黄金比例(1 + sqrt 5)/ 2.由于添加k位整数需要O (k)时间,你的O(n)加法实际上总共需要O(n ^ 2)时间,因为平均而言,你添加的数字有O(n)位。

(对于坚持者来说:大O应该是上面的大Theta。)

答案 1 :(得分:7)

要添加到Reid's answer,您的算法具有O(N)时间复杂度的事实取决于您认为执行的步骤。这是对时间复杂性的常见误解:时间复杂度总是与执行时间相对应。

考虑该步骤取决于我们想要分析问题的深度。如果将步骤定义为Integer的一个加法,是的,带累加器的算法在O(N)时间内运行。如果将步骤定义为一个单词添加(32位或64位加法),则它将以O(N ^ 2)运行,如Reid所述。

如果您希望您的复杂性分析与执行时间相对应,则需要使用执行步骤,执行时间以常量为界,例如添加两个处理器字。添加整数不是,因为整数可以任意大。