Big Theta表示法要求我们找到 2 个常数,k1 和 k2,使得我们的函数 f(n) 在 k1*g(n) 和 k2*g(n) 之间对于足够大的 n。换句话说,我们能否找到一些其他函数 g(n) 在某个点小于 f(n) 而在另一个点大于 f(n)(单调每个方向)。
为了证明 Big-Theta,我们需要找到 g(n) 使得 f(n) 为 O(g(n))(上限),并且 f(n) 为 Big-Omega(g(n))(下限)边界)。
证明大 O
就Big-O表示法(其中 f(n) <= g(n)*k)而言,您的算法 f(n) 为 O(log(n)*n),在这种情况下 g(n) =日志(n)* n。
让我们证明这一点:
查找内循环执行
外循环执行多少次?跟踪“step”变量:假设 n 为 100:
- 1
- 2
- 4
- 8
- 16
- 32
- 64
- 128(不执行此循环)
对于输入 100,这是 7 次执行。我们可以等效地说它执行(log n)
次数(实际上是 floor(log n) 次,但 log(n) 就足够了)。
现在让我们看看内部循环。跟踪 i 变量,该变量从开始n
并递减,直到step
每次迭代都具有大小。因此,对于 step 的每个值,内部 while 循环将执行 n - step 次。
例如,当n = 100
- 100 - 1 = 99 次迭代
- 100 - 2 = 98 次迭代
- 100 - 4 = 96 次迭代
- 100 - 8 = 92 次迭代
- 100 - 16 = 84 次迭代
- 100 - 32 = 68 次迭代
- 100 - 64 = 36 次迭代
那么我们内部循环的总迭代次数是多少?
- (n-1)
- (n-1) + (n-2)
- (n-1) + (n-2) + (n-4)
- (n-1) + (n-2) + (n-4) + (n-8)
- 等等
这东西怎么长的?好吧,因为我们知道外循环会迭代 log(n) 次,所以我们可以将这个东西表述为求和:
Sum(从 i=0 到 log(n)) n-2^i
= log(n)*n - Sum(从 i=0 到 log(n)) 2^i
= log(n)*n - (2^0 + 2^1 + 2^2 + ... + 2^log(n))
= log(n)*n - ( (1-2^log(n) ) / (1-2) ) (实际上是 2^log(n+1) 但足够接近)
= log(n)*n + 1 - n
所以现在我们的目标是证明:
日志(n)*n + 1 - n = O(log(n)*n)
显然,log(n)*n 是 O(log(n)*n),但是1-n
呢?
1-n = O(log(n)*n)?
1-n <= k*log(n)*n,对于一些 k?
让 k = 1
1-n <= log(n)*n?
两边加n
1 <= n*log(n) + n? 是的
所以我们已经证明 f(n) 是 O(n*log(n))。
证明大欧米茄
现在我们使用 log(n) * n 获得了 f(n) 的上限,让我们尝试使用 log(n) * n 获得 f(n) 的下限。
对于下限,我们使用Big Omega表示法。Big Omega 为某个正常数 k 寻找函数 g(n)*k <= f(n)。
k(n*log(n)) <= n*log(n) + 1 - n?
让 k = 1/10
n*log(n)/10 <= n*log(n) + 1 - n?
(n*log(n) - 10n*log(n)) / 10 <= 1 - n?
-9n*log(n)/10 <= 1 - n? 乘以 10
-9n*log(n) <= 10 - 10n?乘以 -1(翻转不等式)
9n*log(n) >= 10n - 10?除以 9
n*log(n) >= 10n/9 - 10/9?除以 n
对数(n) >= 10/9 - 10/9n ? 是的
显然,随着 (10/9 - 10/9n) 趋向于 10/9,log(n) 的数量会变大。事实上,对于 n = 1,0 >= 10/9 - 10/9。0 >= 0。
证明 Big-Theta
所以现在我们已经证明了f(n) is Big-Omega(n*log(n))
。将其与 的证明结合起来f(n) is O(n*log(n))
,我们已经证明了这一点f(n) is Big-Theta(n*log(n))
!(感叹号是为了兴奋,而不是阶乘……)
g(n) = n*log(n),一组有效的常数是k1=1/10(下限)和k2 = 1(上限)。