有人可以帮助解决这种重复关系吗? [关闭]

Posted

技术标签:

【中文标题】有人可以帮助解决这种重复关系吗? [关闭]【英文标题】:Can someone help solve this recurrence relation? [closed] 【发布时间】:2011-04-26 18:21:03 【问题描述】:
T(n) = 2T(n/2) + 0(1)

T(n) = T(sqrt(n)) + 0(1)

在第一个中,我对 n、logn 等使用替换方法;都给了我错误的答案。 递归树:不知道能不能申请,因为根是常数。

有人可以帮忙吗?

【问题讨论】:

我投票结束这个问题,因为它是一个数学问题,而不是一个编程问题。 【参考方案1】:

使用Master Theorem来解决这种递归关系。

a 为大于或等于 1 的整数,b 为大于或等于 1 的实数 1. 令 c 为正实数, d 非负实数。鉴于表单的重复发生

T (n) = a T(n/b) + nc .. 如果 n > 1

T(n) = d .. 如果 n = 1

那么对于 n 的 b 次方,

    如果 logb a c), 如果 logb a = c, T (n) = Θ(nc log n), 如果 logb a > c, T (n) = Θ(nlogb a)。

1) T(n) = 2T(n/2) + 0(1)

在这种情况下

a = b = 2; 日志b a = 1; c = 0(因为 nc =1 => c= 0)

所以情况(3)是适用的。所以T(n) = Θ(n) :)


2) T(n) = T(sqrt(n)) + 0(1)

设 m = log2 n;

=> T(2m) = T( 2m / 2 ) + 0(1)

现在重命名 K(m) = T(2m) => K(m) = K(m/2) + 0(1)

应用案例(2)。


【讨论】:

即使 f(n) 是常数,我也可以应用 masters theorem,例如在这种情况下 0(1) 第二个问题呢? @Ringo:是的,你可以。查看编辑。 第 2 部分不正确。如果2^m = t,那么2^(m/2) 又是sqrt(t)。或者更确切地说,2^m = 2^log n = n,所以替换没有取得任何成果。 @casablanca:谢谢!!已更正。 非常感谢。但是,在第二种情况下,您最终是如何选择 m=lg(n) 的?我的意思是如何猜测?【参考方案2】:

让我们看看第一个递归,T(n) = 2T(n/2) + 1。n/2 是我们的线索:每个嵌套项的参数是其父项的一半。因此,如果我们从 n = 2^k 开始,那么在我们达到基本情况 T(0) 之前,我们将有 k 个项在我们的扩展中,每个项都加 1。因此,假设 T(0) = 1,我们可以说 T(2^k) = k + 1。现在,由于 n = 2^k,我们必须有 k = log_2(n)。因此 T(n) = log_2(n) + 1。

我们可以将相同的技巧应用于您的第二次重复,T(n) = T(n^0.5) + 1。如果我们从 n = 2^2^k 开始,我们将在展开式中有 k 个项,每个项相加总数为 1。假设 T(0) = 1,我们必须有 T(2^2^k) = k + 1。由于 n = 2^2^k,我们必须有 k = log_2(log_2(n)),因此 T(n) = log_2(log_2(n)) + 1.

【讨论】:

【参考方案3】:

对于第 1 部分,您可以按照 @Prasoon Saurav 的建议使用 Master Theorem。

对于第 2 部分,只需扩展循环:

T(n) = T(n ^ 1/2) + O(1)         // sqrt(n) = n ^ 1/2
     = T(n ^ 1/4) + O(1) + O(1)  // sqrt(sqrt(n)) = n ^ 1/4
     etc.

该系列将继续使用k 条款直到n ^ 1/(2^k) <= 1,即2^k = log nk = log log n。这给了T(n) = k * O(1) = O(log log n)

【讨论】:

2^k = log n 是如何导致 k = log log n 的? @casablanca,你能解释一下 【参考方案4】:

让我们看看第一个。首先,你需要知道 T(base case)。你提到它是一个常数,但是当你做这个问题时,把它写下来很重要。通常它类似于 T(1) = 1。我会使用它,但你可以推广到它是什么。

接下来,找出你递归的次数(即递归树的高度)。 n 是您的问题大小,那么我们可以重复将 n 除以 2 多少次?从数学上讲,n/(2^i) = 1 时的我是什么?想清楚,以后再坚持。

接下来,做一些替换,直到你开始注意到一个模式。

T(n) = 2(2(2T(n/2*2*2) + θ(1)) + θ(1)) + θ(1)

好的,模式是我们将 T() 多次乘以 2,然后将 n 除以 2 多次。多少次? i次。

T(n) = (2^i)*T(n/(2^i)) + ...

对于最后的大 θ 项,我们使用了一个可爱的技巧。看看上面我们有几个替换的地方,忽略 T() 部分。我们想要 θ 项的总和。请注意,它们加起来为(1 + 2 + 4 + ... + 2^i) * θ(1)。你能找到1 + 2 + 4 + ... + 2^i 的封闭表格吗?我给你那个;这是(2^i - 1)。只是记住是一个很好的,但是here's how you'd figure it out。

总之,我们得到了所有的东西

T(n) = (2^i) * T(n/(2^i)) + (2^i - 1) * θ(1)

如果您之前解决了i,那么您知道i = log_2(n)。插入它,做一些代数,然后你就可以开始了

T(n) = n*T(1) + (n - 1)*θ(1)T(1) = 1。所以T(n) = n + (n - 1)*θ(1)。即 n 乘以一个常数,加上一个常数,再加上 n。我们去掉了低阶项和常数,所以它是 θ(n)。

Prasoon Saurav 使用主方法是正确的,但重要的是您要知道递归关系在说什么。要问的是,我在每个步骤中做了多少工作,以及n 大小的输入的步骤数是多少?

【讨论】:

【参考方案5】:

递归关系和递归函数也应该从 f(1) 开始求解。在情况 1 中,T(1) = 1; T(2) = 3; T(4) = 7; T(8) = 15;很明显,T(n) = 2 * n -1,在 O 表示法中是 O(n)。 在第二种情况下 T(1) = 1; T(2) = 2; T(4) = 3; T(16) = 4; T(256) = 5; T(256 * 256) =6;很快就会发现 T(n) = log(log(n)) + 1 其中 log 以 2 为底。显然这是 O(log(log(n)) 关系。

【讨论】:

【参考方案6】:

大多数时候处理递归的最好方法是绘制递归树并小心处理基本情况。

不过这里我给你一点提示,用替换法解决。

在循环中首先尝试替换n = 2^k 在重复第二次尝试替换n = 2^2^k

【讨论】:

以上是关于有人可以帮助解决这种重复关系吗? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

有人可以解释这个简单函数中'm'字母的确切含义吗? [重复]

MongoDB运行错误[重复]

强制关闭有很多错误[重复]

有人可以帮助如何转换这个数组[重复]

将对象添加到列表时获取NullPointerException [重复]

C ++重载解决方案[重复]