计数¶
计数是计算概率的前提,你必须在分配可能性之前知道有多少种结果。本文件涵盖了乘法和加法原理、阶乘、排列、组合、二项式系数,这些组合工具是机器学习中抽样、哈希和概率分析的基础。
-
在计算概率之前,我们需要计数结果。如果你想知道在扑克中拿到一手赢牌的概率,你首先需要知道一共有多少手牌,以及其中有多少手是赢牌。计数是使概率精确的机制。
-
最简单的计数原理是乘法原理。如果一个决策有 \(m\) 种选项,另一个独立的决策有 \(n\) 种选项,那么总的组合结果数为 \(m \times n\)。
-
想象一下早上穿衣服。你有 3 件衬衫和 4 条裤子。每件衬衫可以与每条裤子搭配,因此总共有 \(3 \times 4 = 12\) 套搭配。
-
乘法原理可以扩展到任意多个选择。如果你还有 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\) 个不同的物体排成一行有多少种方式?书架上三本书的排列方式有 \(3! = 3 \times 2 \times 1 = 6\) 种。按照惯例,\(0! = 1\)。
-
阶乘增长非常快。\(10! = 3{,}628{,}800\),而 \(20!\) 已经超过 \(2.4 \times 10^{18}\)。这种爆炸式增长正是为什么在组合问题中暴力搜索变得不切实际。
-
排列是物体的有序排列。当你从 \(n\) 个不同物体中选出 \(r\) 个且顺序重要时,排列数为:
-
想象从 10 人的俱乐部中选出主席、副主席和财务主管。第一个角色有 10 名候选人,第二个角色有 9 名,第三个角色有 8 名。这就得到 \(P(10, 3) = 10 \times 9 \times 8 = 720\)。公式验证了这一点:\(\frac{10!}{7!} = 720\)。
-
组合是无序的选择。当你从 \(n\) 个物体中选出 \(r\) 个且顺序不重要时,我们需要除掉冗余的排序:
- 符号 \(\binom{n}{r}\) 读作“n 选 r”。关键在于:每个组合对应 \(r!\) 个排列(选出的 \(r\) 个物体可以以 \(r!\) 种方式重排),所以我们将排列数除以 \(r!\)。
- 示例:从 10 人组中,可以组成多少个 3 人委员会?顺序不重要(没有主席或副主席,只是成员),所以使用组合:
-
同样 10 个人产生 720 种排列,但只有 120 种组合,因为每组 3 人有 \(3! = 6\) 种内部排序。
-
组合是概率的核心。二项式系数 \(\binom{n}{r}\) 统计在 \(n\) 次试验中恰好得到 \(r\) 次成功的方式数,这是二项分布(见文件 03)的核心。
-
让我们通过一个经典的委员会问题来综合运用多种计数思想。
-
问题:一个俱乐部有 8 名男性和 6 名女性。组成一个包含恰好 3 名男性和 2 名女性的 5 人委员会,有多少种方式?
-
步骤 1:从 8 名男性中选 3 人。
- 步骤 2:从 6 名女性中选 2 人。
- 步骤 3:应用乘法原理。每一种男性选择可以与每一种女性选择配对:
-
这种模式——将一个复杂的计数问题分解为独立的子选择并相乘——是组合数学中的标准方法。
-
还有重复排列。当允许重复时,从 \(n\) 种类型中选 \(r\) 个物体,有 \(n^r\) 种结果。使用数字 0-9 的 4 位 PIN 码有 \(10^4 = 10{,}000\) 种可能。每个位置有 10 个选项,乘法原理处理其余部分。
-
重复组合(也称为“星条旗”)统计当允许重复且顺序不重要时,从 \(n\) 种类型中选 \(r\) 个物体的方式数:
-
示例:从 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)¶
-
计算 \(P(10, 3)\) 和 \(\binom{10}{3}\),同时使用阶乘公式和直接计算。验证排列数总是组合数的 \(r!\) 倍。
-
用编程解决委员会问题(8 男选 3,6 女选 2),并通过枚举所有有效委员会进行验证。
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}") -
计算由 26 个小写字母组成的 4 字符密码的数量(允许重复)。然后计算其中不含重复字母的密码数量。
-
模拟生日问题:在 \(k\) 个人中,至少有两人生日相同的概率是多少?绘制 \(k = 1\) 到 \(60\) 的概率图,并找出概率超过 50% 的位置。
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()