Files
flykhan 2536c937e3 feat: 完整中文翻译 maths-cs-ai-compendium(数学·计算机科学·AI 知识大全)
翻译自英文原版 maths-cs-ai-compendium,共 20 章全部完成。

第01章 向量 | 第02章 矩阵 | 第03章 微积分
第04章 统计学 | 第05章 概率论 | 第06章 机器学习
第07章 计算语言学 | 第08章 计算机视觉 | 第09章 音频与语音
第10章 多模态学习 | 第11章 自主系统 | 第12章 图神经网络
第13章 计算与操作系统 | 第14章 数据结构与算法
第15章 生产级软件工程 | 第16章 SIMD与GPU编程
第17章 AI推理 | 第18章 ML系统设计
第19章 应用人工智能 | 第20章 前沿人工智能

翻译说明:
- 所有数学公式 $...$ / $$...$$、代码块、图片引用完整保留
- mkdocs.yml 配置中文导航 + language: zh
- README.md 已翻译为中文(兼 docs/index.md)
- docs/ 目录包含指向各章文件的 symlink
- 约 29,000 行中文内容,排除 .cache/ 构建缓存
2026-05-03 10:23:20 +08:00

168 lines
8.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 计数
*计数是计算概率的前提——在分配可能性之前,你必须先知道有多少种结果。本文涵盖乘法与加法规则、阶乘、排列、组合、二项式系数,以及支撑机器学习中采样、哈希和概率分析的基本组合工具。*
- 在计算概率之前,我们需要先数清结果的数量。如果你想知道在扑克中拿到一手赢牌的概率,你必须先知道一共有多少种可能的牌型,以及其中有多少种是赢牌。计数正是让概率精确化的基础工具。
- 最简单的计数原则是**乘法规则**。如果一个选择有 $m$ 种选项,另一个独立的选择有 $n$ 种选项,那么组合起来的总结果数为 $m \times n$。
- 想象早上穿衣服的场景。你有 3 件衬衫和 4 条裤子。每件衬衫都能与每条裤子搭配,共有 $3 \times 4 = 12$ 种穿搭。
![树状图:3 件衬衫 × 4 条裤子 = 12 种穿搭](../images/counting_outfits.svg)
- 乘法规则可以推广到任意数量的选择。如果你还有 2 双鞋,那么总穿搭数就变成 $3 \times 4 \times 2 = 24$。每个新的独立选择都会乘到总计数中。
- **加法规则**处理"或"的场景。如果事件 A 有 $m$ 种发生方式,事件 B 有 $n$ 种发生方式,且它们不能同时发生(互斥),那么总的方式数为 $m + n$。
- 假设你要从城市 X 前往城市 Y:开车有 3 条路线,坐火车有 2 条路线。你无法同时选择两者,因此总选项数为 $3 + 2 = 5$。
- 当事件有重叠时,需要减去被重复计数的结果。如果 $A$ 和 $B$ 可以同时发生,计数为 $|A \cup B| = |A| + |B| - |A \cap B|$。这就是容斥原理,它将在我们讨论概率加法规则时再次出现。
- 非负整数 $n$ 的**阶乘**是从 1 到 $n$ 的所有正整数的乘积:
$$n! = n \times (n-1) \times (n-2) \times \cdots \times 2 \times 1$$
- 可以将阶乘理解为:将 $n$ 个不同的物体排成一列有多少种方式?三本书在书架上有 $3! = 3 \times 2 \times 1 = 6$ 种排列方式。按约定,$0! = 1$。
- 阶乘的增长速度极快。$10! = 3{,}628{,}800$,而 $20!$ 已经超过 $2.4 \times 10^{18}$。这种爆炸式增长正是暴力搜索在组合问题中变得不切实际的原因。
- **排列**是对物体的有序安排。当你从 $n$ 个不同的物体中选取 $r$ 个且顺序重要时,排列数为:
$$P(n, r) = \frac{n!}{(n - r)!}$$
- 想象从一个 10 人的俱乐部中选出会长、副会长和财务主管。第一个职位有 10 个候选人,第二个有 9 个,第三个有 8 个。因此 $P(10, 3) = 10 \times 9 \times 8 = 720$。公式也印证了这一点:$\frac{10!}{7!} = 720$。
- **组合**是无序的选择。当你从 $n$ 个中选取 $r$ 个且顺序无关紧要时,需要除去重复的排列顺序:
$$C(n, r) = \binom{n}{r} = \frac{n!}{r!(n - r)!}$$
- 符号 $\binom{n}{r}$ 读作"n 选 r"。核心思想是:每个组合对应 $r!$ 种排列(选出的 $r$ 个物品可以有 $r!$ 种重新排列的方式),因此我们将排列数除以 $r!$。
![并列对比:排列计数所有顺序,组合将相同集合合并](../images/permutation_vs_combination.svg)
- 示例:从 10 人中组成一个 3 人委员会有多少种方式?顺序无关紧要(没有会长或副会长之分,只有成员),因此我们使用组合:
$$\binom{10}{3} = \frac{10!}{3! \cdot 7!} = \frac{10 \times 9 \times 8}{3 \times 2 \times 1} = 120$$
- 同样的 10 个人产生 720 种排列,但只有 120 种组合,因为每个 3 人组内部有 $3! = 6$ 种排序方式。
- 组合在概率中至关重要。二项式系数 $\binom{n}{r}$ 统计了在 $n$ 次试验中恰好获得 $r$ 次成功的方式数,这正是二项分布(见文件 03)的核心。
- 让我们通过一个经典的委员会问题来综合运用多种计数思路。
- **问题**:一个俱乐部有 8 名男性和 6 名女性。要组成一个 5 人委员会,其中恰好包含 3 名男性和 2 名女性,有多少种方式?
- **第 1 步**:从 8 人中选 3 名男性。
$$\binom{8}{3} = \frac{8!}{3! \cdot 5!} = \frac{8 \times 7 \times 6}{3 \times 2 \times 1} = 56$$
- **第 2 步**:从 6 人中选 2 名女性。
$$\binom{6}{2} = \frac{6!}{2! \cdot 4!} = \frac{6 \times 5}{2 \times 1} = 15$$
- **第 3 步**:应用乘法规则。每种男性选择可以与每种女性选择配对:
$$56 \times 15 = 840 \text{ 个委员会}$$
- 这种将复杂计数问题分解为独立子选择再相乘的模式,是组合数学中的标准方法。
- 还有**可重复的排列**。当物品可以重复时,从 $n$ 种类型中选 $r$ 个会产生 $n^r$ 种结果。一个使用数字 0-9 的 4 位 PIN 码有 $10^4 = 10{,}000$ 种可能性。每一位都有 10 种选择,乘法规则即可解决。
- **可重复的组合**(也称"星条法")统计从 $n$ 种类型中选 $r$ 个、允许重复且顺序无关的方式数:
$$\binom{n + r - 1}{r} = \frac{(n + r - 1)!}{r!(n - 1)!}$$
- 示例:从 4 种冰淇淋口味中选择 3 勺(允许重复)有 $\binom{4 + 3 - 1}{3} = \binom{6}{3} = 20$ 种选项。
- 总结计数工具箱:
| 场景 | 公式 |
|---|---|
| 有序,无重复(排列) | $P(n,r) = \frac{n!}{(n-r)!}$ |
| 无序,无重复(组合) | $\binom{n}{r} = \frac{n!}{r!(n-r)!}$ |
| 有序,可重复 | $n^r$ |
| 无序,可重复 | $\binom{n+r-1}{r}$ |
- 每个涉及等可能结果(等概率结果)的概率计算都使用公式 $P(\text{事件}) = \frac{\text{有利结果数}}{\text{总结果数}}$。计数为我们提供了这两个数字。有了这个基础,我们将在下一个文件中正式定义概率本身。
## 编程练习(在 CoLab 或 notebook 中完成)
1. 使用阶乘公式和直接计算两种方式计算 $P(10, 3)$ 和 $\binom{10}{3}$。验证排列数总是组合数的 $r!$ 倍。
```python
import jax.numpy as jnp
from math import factorial
n, r = 10, 3
perm = factorial(n) // factorial(n - r)
comb = factorial(n) // (factorial(r) * factorial(n - r))
print(f"P({n},{r}) = {perm}")
print(f"C({n},{r}) = {comb}")
print(f"P / C = {perm // comb} (应等于 {r}! = {factorial(r)})")
```
2. 通过程序解决委员会问题(8 人中选 3 名男性,6 人中选 2 名女性),并通过枚举所有有效委员会来验证。
```python
from itertools import combinations
from math import factorial
def comb_count(n, r):
return factorial(n) // (factorial(r) * factorial(n - r))
# 公式法
men_ways = comb_count(8, 3)
women_ways = comb_count(6, 2)
print(f"公式法: {men_ways} × {women_ways} = {men_ways * women_ways}")
# 枚举法
men = [f"M{i}" for i in range(1, 9)]
women = [f"W{i}" for i in range(1, 7)]
count = sum(1 for _ in combinations(men, 3) for _ in combinations(women, 2))
print(f"枚举法: {count}")
```
3. 统计由 26 个小写字母组成的 4 位密码有多少种(允许重复)。然后统计没有重复字母的密码有多少种。
```python
from math import factorial
n = 26
r = 4
with_rep = n ** r
without_rep = factorial(n) // factorial(n - r)
print(f"允许重复: {with_rep:>10,}")
print(f"不允许重复: {without_rep:>10,}")
print(f"含重复的比例: {1 - without_rep/with_rep:.2%}")
```
4. 模拟生日问题:在 $k$ 人的群体中,至少两人共享生日的概率是多少?绘制 $k = 1$ 到 $60$ 的概率曲线,并找出概率超过 50% 的位置。
```python
import jax
import jax.numpy as jnp
import matplotlib.pyplot as plt
def birthday_prob_exact(k):
\"\"\"k 人群体中至少有一对共享生日的概率。\"\"\"
p_no_match = 1.0
for i in range(k):
p_no_match *= (365 - i) / 365
return 1 - p_no_match
ks = list(range(1, 61))
probs = [birthday_prob_exact(k) for k in ks]
plt.figure(figsize=(8, 4))
plt.plot(ks, probs, color="#3498db", linewidth=2)
plt.axhline(y=0.5, color="#e74c3c", linestyle="--", alpha=0.7, label="50%")
cross = next(k for k, p in zip(ks, probs) if p >= 0.5)
plt.axvline(x=cross, color="#e74c3c", linestyle="--", alpha=0.7)
plt.xlabel("群体大小 (k)")
plt.ylabel("P(至少两人共享生日)")
plt.title(f"生日问题(在 k={cross} 时超过 50%")
plt.legend()
plt.grid(alpha=0.3)
plt.show()
```