简体   繁体   English

Haskell中的整数时间复杂度

[英]Integer time complexity in Haskell

I had an assignment in school last week to implement a function for calculating the n:th number in the fibonacci sequence. 我上周在学校做了一项任务,实现了计算斐波纳契数列中第n个数的函数。 A 'sub-assignment' was to implement it using accumulation(Might not be a correct translation) in order to give the function O(n) time complexity. “子指派”是使用累积(可能不是正确的翻译)来实现它,以便给出函数O(n)时间复杂度。 This all worked fine until I tried making the function (Int -> Integer). 这一切都很好,直到我尝试制作函数(Int - > Integer)。 By experimenting a bit I realised that the time complexity was close to O(n^2) for really large numbers. 通过实验,我意识到时间复杂度对于非常大的数字接近于O(n ^ 2)。 It occurs to me that this must be because of the Integer implementation, which makes me a bit curious about how it works. 在我看来,这必须是因为Integer的实现,这使我对它的工作方式有点好奇。 I did a few Google searches and didn't find anything that seemed useful so I am turning to you guys in hope of either getting an explanation or a link that explains it thoroughly. 我做了一些谷歌搜索,没有找到任何看似有用的东西,所以我转向你们,希望得到一个解释或一个解释彻底的链接。

My code: 我的代码:

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"

I am thankful for all answers 我很感谢所有答案

Viktor

This has nothing to do with Haskell really, it's just a result of the fact that the Fibonacci numbers grow exponentially quickly. 这与Haskell无关,这只是Fibonacci数量迅速呈指数增长的结果。 Specifically, the nth Fibonacci number has about (log 2 φ) n or roughly 0.48 n bits where φ is the golden ratio (1 + sqrt 5) / 2. Since addition of k-bit integers takes O(k) time, your O(n) additions actually take a total of O(n^2) time, because on average the numbers you're adding have O(n) bits. 具体而言,第n个斐波那契数已约(日志2φ)n或大致0.48的n位,其中φ是黄金比例(1 + SQRT 5)/ 2,由于除了k位整数的花费O(k)的时间,你的O (n)加法实际上总共需要O(n ^ 2)时间,因为平均而言,你添加的数字有O(n)位。

(Note for sticklers: big O should really be big Theta in the above.) (注意粘贴:大O应该是上面的大Theta。)

To add to Reid's answer , the fact that your algorithm has O(N) time complexity depends on what you consider to be the step of execution. 要添加到Reid的答案 ,您的算法具有O(N)时间复杂度的事实取决于您认为是执行步骤。 This is a common misconception of time complexity: that time complexity always corresponds to execution time. 这是对时间复杂性的常见误解:时间复杂度始终与执行时间相对应。

What to consider the step depends on how deep we want to analyse the issue. 要考虑的步骤取决于我们想要分析问题的深度。 If you define a step as one addition of Integer, yes, your algorithm with accumulators runs in O(N) time. 如果将步骤定义为Integer的一个加法,是的,带累加器的算法在O(N)时间内运行。 If you define a step as one word addition (a 32- or 64-bit addition), it runs in O(N^2) as Reid explained. 如果将步骤定义为一个单词添加(32位或64位加法),则它将以O(N ^ 2)运行,如Reid所述。

If you want your complexity analysis to correspond to the execution time you need to use a step of execution whose execution time is bounded above by a constant, like the addition of two processor words. 如果您希望您的复杂性分析与执行时间相对应,则需要使用执行步骤,其执行时间以常量为界,例如添加两个处理器字。 Addition of Integers is not, because Integers can be arbitrarily large. 添加整数不是,因为整数可以任意大。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM