我一直在研究最近的计算机科学作业,涉及递归和大O符号。我相信我很了解这一点(当然不是很完美!)但是有一个问题特别是给我最多的问题。奇怪的是,通过查看,它看起来是家庭作业中最简单的一个。
使用big-Oh表示法提供最佳的增长率以解决以下重现问题?
T(1)= 2
对于n> 1,T(n)= 2T(n-1)+ 1
选择是:
我理解大O作为一个上限,用于描述该程序或过程将采取的大部分计算或最高运行时间。我觉得这个特殊的递归应该是O(n),因为最多只有n的每个值都会发生一次递归。由于n不可用,它要么比O(nlogn)好,要么更糟,是其他三个选项。
所以,我的问题是:为什么不是这个O(n)?
答案 0 :(得分:17)
有几种不同的方法可以解决重现:替换,递归树和主定理。主定理在这种情况下不起作用,因为它不符合主定理形式。
您可以使用其他两种方法,但解决此问题的最简单方法是迭代解决。
T(n)= 2T(n-1)+ 1
T(n)= 4T(n-2)+ 2 + 1
T(n)= 8T(n-3)+ 4 + 2 + 1
T(n)= ...
看模式?
T(n)= 2 n-1 ·T(1)+ 2 n-2 + 2 n-3 +。 .. + 1
T(n)= 2 n-1 2 + 2 n-2 + 2 n-3 + ... + 1
T(n)= 2 n + 2 n-2 + 2 n-3 + ... + 1
因此,最严格的界限是Θ(2 n )。
答案 1 :(得分:15)
我认为你有点误解了这个问题。它没有问你解决复发需要多长时间。它问的是解决方案本身的大O(渐近界限)是什么。
你要做的就是想出一个封闭的形式解决方案,i。即T(n)的非递归公式,然后确定该表达式的大O是什么。
答案 2 :(得分:2)
我认为这将是指数级的。每增加一个n,就会使值变为两倍。
T(2) = 2 * T(1) = 4
T(3) = 2 * T(2) = 2 * 4
...
T(x)将是以下程序的运行时间(例如):
def fn(x):
if (x == 1):
return # a constant time
# do the calculation for n - 1 twice
fn(x - 1)
fn(x - 1)
答案 3 :(得分:2)
问题是要求重复解决方案的大哦符号,而不是重复计算的成本。
换句话说:重复产生:
1 -> 2
2 -> 5
3 -> 11
4 -> 23
5 -> 47
什么大哦符号最能描述序列2,5,11,23,47 ......
解决这个问题的正确方法是求解递推方程。
答案 4 :(得分:1)
我认为这将是指数级的。每增加一个n就会带来两倍的计算量。
不,它没有。恰恰相反:
考虑到 n 迭代,我们得到 R 的运行时间。然后对于 n + 1次迭代,我们将得到 R + 1。
因此,增长率是恒定的,整个运行时确实 O ( n )。
然而,我认为Dima关于这个问题的假设是正确的,尽管他的解决方案过于复杂:
你要做的就是想出一个封闭的形式解决方案,i。即T(n)的非递归公式,然后确定该表达式的大O是什么。
检查 T ( n )和 T ( n + 1)的相对大小就足够了迭代并确定相对增长率。数量明显加倍,直接给出了渐近增长。
答案 5 :(得分:1)
首先,所有四个答案都比O(n)差...... O(n * log n)比普通的旧O(n)更复杂。什么更大:8或8 * 3,16或16 * 4等...
关于实际问题。如果你不进行递归
,显然可以在恒定时间内解决一般解决方案(T(n)= 2 ^(n - 1)+ 2 ^(n) - 1),所以这不是他们所要求的。
正如您所看到的,如果我们编写递归代码:
int T( int N )
{
if (N == 1) return 2;
return( 2*T(N-1) + 1);
}
显然是O(n)。
所以,这似乎是一个措辞严厉的问题,他们可能会问你函数本身的增长,而不是代码的复杂性。那是2 ^ n。现在去完成其余的功课......并研究O(n * log n)
答案 6 :(得分:1)
计算递归的封闭形式解决方案很容易。 通过检查,您猜测解决方案是
T(n) = 3*2^(n-1) - 1
然后你通过归纳证明这确实是一个解决方案。基本情况:
T(1) = 3*2^0 - 1 = 3 - 1 = 2. OK.
诱导:
Suppose T(n) = 3*2^(n-1) - 1. Then T(n+1) = 2*T(n) + 1 = 3*2^n - 2 + 1 = 3*2^((n+1)-1) - 1. OK.
第一个等式来自重复定义, 而第二个来自归纳假设。 QED。
3 * 2 ^(n-1) - 1显然是Theta(2 ^ n),因此正确的答案是第三个。
回答O(n)的人:我不能同意Dima。问题确实不要求算法计算复杂度的最严格上限来计算T(n)(现在为O(1),因为已经提供了封闭形式)。问题要求T(n)本身上的最紧密上限,这是指数的。