无法弄清楚这种重复的复杂性

Posted

技术标签:

【中文标题】无法弄清楚这种重复的复杂性【英文标题】:Can not figure out complexity of this recurrence 【发布时间】:2013-01-03 15:12:31 【问题描述】:

我对 Master Theorem 有点耳目一新,我试图通过递归求解 2 个大小为 n-1 的子问题并在恒定时间内组合解决方案来计算解决大小为 n 的问题的算法的运行时间。 所以公式是:T(N) = 2T(N - 1) + O(1) 但我不确定如何制定主定理的条件。 我的意思是我们没有T(N/b),所以在这种情况下,主定理公式的bb=N/(N-1)? 如果是,因为显然是a > b^k,因为k=0 并且是O(N^z),其中z=log2 的基数为(N/N-1),我怎么能理解这一点?假设我到目前为止是对的?

【问题讨论】:

首先,这是错误的定义,因为需要定义 T(1),所以我们将其定义为 T1。其次,这实际上是一阶线性递推关系。我会给你一个提示。这样看:x[n] = a x[n-1] + c 【参考方案1】:

啊,提示就够了。解决方案其实很简单。对两边进行z变换,对项进行分组,然后进行z逆变换得到解。

首先,把问题看成是

    x[n] = a x[n-1] + c

在两边都应用 z 变换(关于 ROC 有一些技术细节,但我们现在先忽略它)

    X(z) = (a X(z) / z) + (c z / (z-1))

求解 X(z) 得到

    X(z) = c z^2 / [(z - 1) * (z-a)]

现在观察这个公式可以重写为:

    X(z) = r z / (z-1) + s z / (z-a)

其中 r = c/(1-a) 和 s = - a c / (1-a)

此外,请注意

    X(z) = P(z) + Q(z)

其中 P(z) = rz / (z-1) = r / (1 - (1/z)),并且 Q(z) = sz / (za) = s / (1 - a (1/ z))

应用逆 z 变换得到:

    p[n] = r u[n] 

    q[n] = s exp(log(a)n) u[n]

其中 log 表示自然对数,u[n] 是单位(Heaviside)阶跃函数(即 u[n]=1 表示 n>=0,u[n]=0 表示 n

最后,通过 z 变换的线性:

    x[n] = (r + s exp(log(a) n))u[n]

其中 r 和 s 定义如上。

所以重新标记回到你原来的问题,

    T(n) = a T(n-1) + c

然后

    T(n) = (c/(a-1))(-1+a exp(log(a) n))u[n]

其中exp(x) = e^x,log(x)是x的自然对数,u[n]是单位阶跃函数。

这告诉你什么?

除非我犯了错误,否则 T 会随着 n 呈指数增长。在 a > 1 的合理假设下,这实际上是一个指数增长的函数。指数由 a(更具体地说,a 的自然对数)控制。

再简化一点,注意exp(log(a) n) = exp(log(a))^n = a^n:

    T(n) = (c/(a-1))(-1+a^(n+1))u[n]

大 O 表示法中的 O(a^n)。

现在是最简单的方法:

把 T(0) = 1

    T(n) = a T(n-1) + c

    T(1) = a * T(0) + c = a + c
    T(2) = a * T(1) + c = a*a + a * c + c
    T(3) = a * T(2) + c = a*a*a + a * a * c + a * c + c
    ....

请注意,这会创建一个模式。具体来说:

    T(n) = sum(a^j c^(n-j), j=0,...,n)

把 c = 1 给

    T(n) = sum(a^j, j=0,...,n)

这是几何级数,计算结果为:

    T(n) = (1-a^(n+1))/(1-a)
         = (1/(1-a)) - (1/(1-a)) a^n
         = (1/(a-1))(-1 + a^(n+1))

对于 n>=0。

请注意,此公式与上面给出的 c=1 使用 z 变换方法相同。再次,O(a^n)。

【讨论】:

我为这个蹩脚的问题道歉,但 ROC 是什么?我什至不记得 z-transform 是什么。但你的解决方案与教科书解决方案的结果相同。所以 +1跨度> @Cratylus,我添加了简单的方法,这可能更符合您正在学习的内容。似乎您可以扩展术语并注意到它是一个几何级数。对于这个等式来说,这是幸运的。它并不总是那么干净。 z 变换方法适用于高于 1 的阶数和时髦的组合。例如,如果 T(n) = a T(n-1) + b T(n-2) + c T(n-3) + d。简单的扩展并不总是很好。无论如何,对我来说很好的复习。超过 15 年没有做过这些事情了。 似乎是正确的答案,但我必须研究它才能理解它。对我来说太高级了 很好的答案。 +1 用于使用 z 变换的分析证明。【参考方案2】:

甚至不要考虑大师定理。当从一般形式 T(n) = aT(n/b) + f(n) 中得到 b > 1 时,您只能使用 Masther 定理。

相反,这样想。您有一个递归调用,它在每次递归调用时将输入的大小 n 减 1。并且在每次递归调用中,成本都是常数 O(1)。输入大小将递减,直到达到 1。然后将用于进行递归调用的所有成本加起来。 他们有几个人? n.所以这需要 O(2^n)。

【讨论】:

更正了 OP 中的一个错字。在公式中写了a 而不是2。这会改变你的答案吗? 我的 OP 是关于如何将主定理应用于具有 a bk 重复值的公式 正如我上面解释的,你不能直接将大师定理的公式应用于这个。但是你可以画出大师定理所基于的递归树,并计算出总时间。 +1 指出 b>1 在主定理中!我完全忘记了! 对不起我的第二条评论,实际上是 O(2^n)。这是因为您在每一步都进行了两次递归调用。然后,递归调用的次数会随着 n 变为 1 呈指数增长。【参考方案3】:

看起来你不能用主定理来表述这个问题。

一个好的开始是绘制递归树来理解模式,然后用替换方法证明它。您还可以将公式展开几次,看看它的结果。

另请参阅解决 2 个子问题而不是 a 的问题: Time bound for recursive algorithm with constant combination time

【讨论】:

更正了 OP 中的一个错字。在公式中写了 a 而不是 2。这会改变你的答案吗?【参考方案4】:

也许你可以这样想

什么时候

n = 1, T(1) = 1
n = 2, T(2) = 2
n = 3, T(3) = 4
n = 4, T(4) = 8
n = 5, T(5) = 16

很容易看出这是一个几何级数1 + 2+ 4+ 8 + 16...,其和是 第一学期(ratio^n - 1)/(ratio - 1)。对于这个系列是

1 * (2^n - 1)/(2 - 1) = 2^n - 1.

这里的主导词是2^n,因此函数属于Theta(2^n)。你可以通过lim(n->inf) [2^n / (2^n - 1)] = +ve constant.来验证它

因此该函数属于Big Theta (2^n)

【讨论】:

以上是关于无法弄清楚这种重复的复杂性的主要内容,如果未能解决你的问题,请参考以下文章

在这种复杂情况下,如何解决 Django 缺少组合键的问题?

Java,无法弄清楚如何从回文字符串中删除符号

无法弄清楚为啥我的注销按钮不起作用(php)[重复]

无法弄清楚为啥我在我的 jsonp 序列化中得到重复数据

无法弄清楚如何在 Python 3.5 中杀死子进程 [重复]

无法弄清楚如何显示只有相同值的表数据[重复]