concat的运行时间分析

时间:2018-08-17 16:29:13

标签: haskell functional-programming time-complexity

这是理查德·伯德(Richard Bird)的《从功能与思维》(Haskell)的思考(第158页)中的一个例子。有人可以解释一下1,2,3和4背后的原因吗?

编辑。 我了解由第一个定义形成的前三个方程。对于1.,为什么要求和?它与T(++)(n,m)=Θ(n)的关系如何? 对于第二个定义,我理解前两个语句。第三个(2.),为什么是k + n? 对于3和4。我完全迷路了


首先考虑concat的以下两个定义:

concat xss= foldr (++) [] xss 
concat' xss = foldl (++) [] xss 

如果xss是一个有限列表,则这两个定义是等效的。假设xss是长度为m的列表,长度为n。然后第一个定义给出

T(concat)(m, n) = T(foldr (++) [])(m, n),
T(foldr (++) [])(0, n) = Θ(1), 
T(foldr (++) [])(m+1, n) = T(++)(n, mn) + T(foldr (++) [])(m, n). 

之所以产生估计值T(++)(n,mn),是因为将长度为n的列表与长度为mn的列表连接在一起。由于T(++)(n,m)=Θ(n),我们得到

1. T(foldr (++) [])(m,n) = Σ_{k=0}^{m} Θ(n) = Θ(mn)

对于concat的第二个定义,我们有

T(concat')(m, n) = T(foldl (++))(0, m, n),  
T(foldl (++))(k, 0, n) = O(1), 
2. T(foldl (++))(k, m+1, n) = T(++)(k, n) + T(foldl (++))(k+n, m, n).

附加参数k表示foldl的第二个参数中累加列表的长度。这次我们获得了

3. T(foldl (++)) (k,m,n) = Σ_{j=0}{m-1} Θ(k+jn) = Θ(k+m^2n)

因此

4. T(concat')(m, n) = Θ(m_2 n)

1 个答案:

答案 0 :(得分:1)

  

对于1.,为什么要求和?它与T(++)(n, m) = Θ(n)有何关系?

总和来自归纳定义。考虑这个独立的定义

g(0,n) = something
g(m+1,n) = f(m,n) + g(m,n)

通过归纳,我们得到

g(m,m)
= f(m-1,n) + g(m-1,n)
= f(m-1,n) + f(m-2,n) + g(m-2,n)
= f(m-1,n) + f(m-2,n) + f(m-3,n) + g(m-3,n)
= f(m-1,n) + f(m-2,n) + f(m-3,n) + ... + f(m-m,n) + g(m-m,n)
= f(m-1,n) + f(m-2,n) + f(m-3,n) + ... + f(m-m,n) + something

因此,结果是f(n,x)的总和,其中x有所不同,加上最后一项something

在原始定义中,g(m,n)T(foldr (++) [])(m, n),而 f(m,n) = T(++)(n, mn)。最后一个术语无所谓,渐近。

  

对于第二个定义,我理解前两个语句。   第三个(2.),为什么是k + n?

在计算foldl (++) x ys时,假设x是长度为k的列表,而ys是长度为{{1}的列表的列表},其元素的长度为m+1

现在,递归n方程为:

foldl

递归调用的成本包括(A)foldl (++) x (y:ys) = foldl (++) (x++y) ys 的成本,即temp = x++y,和(B)T(++)(k, n)的成本。对于(B),foldl (++) temp ys的长度现在为temp,而length x + length y = k+n的长度为ysm不受影响)。

所以,我们得到了

n
  

对于3.和4.我完全迷失了

在3.中,与对1.所做的一样,我们将T(foldl (++))(k, m+1, n) = A + B = T(++)(k, n) + T(foldl (++))(k+n, m, n). 的项与T(++)(k, n)进行变化。请注意,每次递归,k都会增加k,因此我们得到

n

在4中,我们选择T(++)(k, n) + T(++)(k+n, n) + T(++)(k+n+n, n) + ... = Σ_{j=0}{m-1} T(++)(k+jn, n) = Σ_{j=0}{m-1} Θ(k+jn) = Θ(k+m^2 n) ,因为在k=0的定义中,我们最初选择了长度为concat'的{​​{1}}。因此,只有x=[]可以生存。