Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

修复2.8.5 log 相关公式部分 #169

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions sicp/2/8.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,19 +225,19 @@ $$
1267650600228229401496703205376
```

通过快速指数运算(`fast_exp`),计算过程在时间和空间上都以对数级别随 $n$ 增长。要理解这一点,观察一下使用 `fast_exp` 计算 $b$ 的 $2n$ 次幂仅仅比计算 $b$ 的 $n$ 次幂多进行一次乘法。因此,我们可以看到每一次允许的新乘法使得我们能够计算的指数大小翻倍(粗略估计)。因此,对于指数 $n$ ,所需的乘法次数大致以 2 为底数的 $n$ 的对数增长。这个过程具有 $Θ(log_{n})$ 的增长阶。
通过快速指数运算(`fast_exp`),计算过程在时间和空间上都以对数级别随 $n$ 增长。要理解这一点,观察一下使用 `fast_exp` 计算 $b$ 的 $2n$ 次幂仅仅比计算 $b$ 的 $n$ 次幂多进行一次乘法。因此,我们可以看到每一次允许的新乘法使得我们能够计算的指数大小翻倍(粗略估计)。因此,对于指数 $n$ ,所需的乘法次数大致以 2 为底数的 $n$ 的对数增长。这个过程具有 $Θ(\log_{}{n})$ 的增长阶。

当 $n$ 变得很大时, $Θ(log_{n})$ 增长阶与 $Θ(n)$ 增长阶之间的差异会变得非常明显。例如,对于 $n$ 为 1000,使用 `fast_exp` 只需要 14 次乘法,而不是 1000 次。这显示了使用快速指数运算相对于普通指数运算在效率上的巨大优势。
当 $n$ 变得很大时, $Θ(\log_{}{n})$ 增长阶与 $Θ(n)$ 增长阶之间的差异会变得非常明显。例如,对于 $n$ 为 1000,使用 `fast_exp` 只需要 14 次乘法,而不是 1000 次。这显示了使用快速指数运算相对于普通指数运算在效率上的巨大优势。

## 2.8.5 增长类别

增长阶是为了简化计算过程的分析和比较而设计的。许多不同的计算过程可以具有等效的增长阶,这表示它们的增长方式相似。对于计算机科学家来说,了解和识别常见的增长阶并确定具有相同增长阶的过程是一项重要的技能。

**常数项**:常数项不影响计算过程的增长阶。因此,例如, $Θ(n)$ 和 $Θ(500⋅n)$ 具有相同的增长阶。这个性质来自于 $Θ$ 符号的定义,它允许我们选择任意的常数 $k_1$ 和 $k_2$(比如 $\frac{1}{500}$ )作为上界和下界。为了简洁起见,增长阶中常数通常被忽略。
**常数项:** 常数项不影响计算过程的增长阶。因此,例如, $Θ(n)$ 和 $Θ(500⋅n)$ 具有相同的增长阶。这个性质来自于 $Θ$ 符号的定义,它允许我们选择任意的常数 $k_1$ 和 $k_2$(比如 $\frac{1}{500}$ )作为上界和下界。为了简洁起见,增长阶中常数通常被忽略。

**对数**:对数的底数不影响计算过程的增长阶。例如,$log2(n)$ 和 $log10(n)$ 具有相同的增长阶。改变对数的底数等价于乘以一个常数因子。
**对数:** 对数的底数不影响计算过程的增长阶。例如,$\log_{2}{n}$ 和 $\log_{10}{n}$ 具有相同的增长阶。改变对数的底数等价于乘以一个常数因子。

**嵌套**:当内部的计算过程在外部过程的每一步中重复执行时,整个过程的增长阶是外部和内部过程的步骤数的乘积。
**嵌套:** 当内部的计算过程在外部过程的每一步中重复执行时,整个过程的增长阶是外部和内部过程的步骤数的乘积。

例如,下面的函数 `overlap` 计算列表 `a` 中与列表 `b` 中出现的元素数量。

Expand All @@ -255,7 +255,7 @@ $$

对于列表的 `in` 运算符,其时间复杂度为 $Θ(n)$ ,其中 $n$ 是列表 `b` 的长度。它被应用 $Θ(m)$ 次,其中 $m$ 是列表 `a` 的长度。表达式 `item in b` 是内部过程,而 `for item in a` 循环是外部过程。该函数的总增长阶是 $Θ(m⋅n)$ 。

低阶项随着计算过程的输入增长,计算中增长最快的部分将主导总的资源使用。$Θ$ 符号捕捉了这种直觉。总的来说,除了增长最快的项外,其他项都可以忽略而不影响增长阶。
**低阶项:** 随着计算过程的输入增长,计算中增长最快的部分将主导总的资源使用。$Θ$ 符号捕捉了这种直觉。总的来说,除了增长最快的项外,其他项都可以忽略而不影响增长阶。

例如,考虑函数 `one_more`,它返回列表 `a` 中有多少个元素是另一个元素的值加 1。也就是说,在列表 `[3, 14, 15, 9]` 中,元素 15 比 14 大 1,所以 `one_more` 将返回 1。

Expand All @@ -271,12 +271,12 @@ $$

$Θ(n^2 + k*n)$ 和 $Θ(n^2)$ 对于任意常数 $k$ 来说是等价的,因为对于任何 $k$,$n^2$ 项在足够大的 $n$ 下将主导总和。这里的边界要求仅对于大于某个最小值 $m$ 的 $n$ 成立,从而确立了这种等价性。为简洁起见,增长阶中的低阶项通常被忽略,所以我们不会在 $theta$ 表达式中看到求和。

**常见的类别** 通过这些等价性,我们可以得到一小组常见的类别来描述大多数计算过程。最常见的类别如下,按从最慢到最快的增长顺序列出,并描述了随着输入增加而增长的情况。接下来将给出每个类别的例子。
**常见的类别:** 通过这些等价性,我们可以得到一小组常见的类别来描述大多数计算过程。最常见的类别如下,按从最慢到最快的增长顺序列出,并描述了随着输入增加而增长的情况。接下来将给出每个类别的例子。

| 类别 | $Θ$ 表示 | 增长阶描述 | 例子 |
| ---- | ------------ | ------------------------------------------------- | ---------- |
| 常数 | $Θ(1)$ | 增长与输入无关 | `abs` |
| 对数 | $Θ(log_{n})$ | 增长与输入的大小成正比 | `fast_exp` |
| 对数 | $Θ(\log_{}{n})$ | 增长与输入的大小成正比 | `fast_exp` |
| 线性 | $Θ(n)$ | 随着输入的递增,计算过程所需的资源会增加 n 个单位 | `exp` |
| 乘方 | $Θ(n^2)$ | 随着输入的递增,计算过程所需的资源会增加 n 个单位 | `one_more` |
| 指数 | $Θ(b^n)$ | 随着输入的递增,计算过程所需的资源会成倍增加 | `fib` |
Expand Down