第三十五 离散数学(Discrete Mathematics)
离散数学是研究离散量的结构及其相互关系的数学分支,与连续数学(如微积分)相对。它是计算机科学的理论基础,为算法设计、数据结构、数据库、编译原理、密码学等提供了核心数学工具。
一、集合论
1.1 基本概念
集合:一组确定的、互不相同的对象的全体。集合中的对象称为元素。
| 符号 | 含义 |
|---|---|
| $a \in A$ | $a$ 属于集合 $A$ |
| $a \notin A$ | $a$ 不属于集合 $A$ |
| $\emptyset$ | 空集 |
| $|A|$ | 集合 $A$ 的元素个数(基数) |
| $\mathcal{U}$ | 全集 |
1.2 集合间的关系
| 关系 | 符号 | 定义 |
|---|---|---|
| 子集 | $A \subseteq B$ | $A$ 的每个元素都属于 $B$ |
| 真子集 | $A \subset B$ | $A \subseteq B$ 且 $A \neq B$ |
| 相等 | $A = B$ | $A \subseteq B$ 且 $B \subseteq A$ |
1.3 集合运算
| 运算 | 符号 | 定义 |
|---|---|---|
| 并集 | $A \cup B$ | 属于 $A$ 或属于 $B$ 的元素 |
| 交集 | $A \cap B$ | 同时属于 $A$ 和 $B$ 的元素 |
| 差集 | $A - B$ | 属于 $A$ 但不属于 $B$ 的元素 |
| 补集 | $\bar{A}$ | 属于全集但不属于 $A$ 的元素 |
| 对称差 | $A \triangle B$ | $(A - B) \cup (B - A)$ |
运算律:
$$A \cup B = B \cup A \quad \text{(交换律)}$$ $$A \cap (B \cup C) = (A \cap B) \cup (A \cap C) \quad \text{(分配律)}$$ $$\overline{A \cup B} = \bar{A} \cap \bar{B} \quad \text{(德摩根定律)}$$ $$\overline{A \cap B} = \bar{A} \cup \bar{B} \quad \text{(德摩根定律)}$$
use std::collections::{HashSet, BTreeSet};
fn main() {
let a: HashSet<i32> = [1, 2, 3, 4].iter().cloned().collect();
let b: HashSet<i32> = [3, 4, 5, 6].iter().cloned().collect();
// 并集
let union: BTreeSet<_> = a.union(&b).cloned().collect();
println!("A ∪ B = {:?}", union); // {1, 2, 3, 4, 5, 6}
// 交集
let intersection: BTreeSet<_> = a.intersection(&b).cloned().collect();
println!("A ∩ B = {:?}", intersection); // {3, 4}
// 差集
let difference: BTreeSet<_> = a.difference(&b).cloned().collect();
println!("A - B = {:?}", difference); // {1, 2}
// 对称差
let sym_diff: BTreeSet<_> = a.symmetric_difference(&b).cloned().collect();
println!("A △ B = {:?}", sym_diff); // {1, 2, 5, 6}
}
1.4 幂集
集合 $A$ 的幂集 $\mathcal{P}(A)$ 是 $A$ 的所有子集构成的集合。
$$|\mathcal{P}(A)| = 2^{|A|}$$
fn power_set<T: Clone>(set: &[T]) -> Vec<Vec<T>> {
let n = set.len();
let mut result = Vec::new();
for mask in 0..(1u32 << n) {
let mut subset = Vec::new();
for i in 0..n {
if (mask >> i) & 1 == 1 {
subset.push(set[i].clone());
}
}
result.push(subset);
}
result
}
fn main() {
let set = vec![1, 2, 3];
let ps = power_set(&set);
println!("幂集(共 {} 个子集):", ps.len()); // 8 = 2³
for subset in &ps {
println!(" {:?}", subset);
}
}
二、图论
2.1 基本概念
图 $G = (V, E)$ 由顶点集 $V$ 和边集 $E$ 组成。
| 概念 | 定义 |
|---|---|
| 有向图 | 边有方向 |
| 无向图 | 边无方向 |
| 完全图 $K_n$ | 任意两个顶点之间都有边 |
| 度 | 与顶点相连的边数 |
| 路径 | 顶点与边交替的序列 |
| 回路 | 起点和终点相同的路径 |
| 连通图 | 任意两个顶点之间都有路径 |
| 树 | 连通且无回路的图 |
握手定理: 无向图中所有顶点的度数之和等于边数的两倍:
$$\sum_{v \in V} \deg(v) = 2|E|$$
2.2 七桥问题
七桥问题是图论的起源。欧拉证明了:一个图存在一笔画(欧拉路径)的充要条件是:恰好有 0 个或 2 个奇数度的顶点。
- 0 个奇数度顶点 → 欧拉回路(起点和终点相同)
- 2 个奇数度顶点 → 欧拉路径(起点和终点不同)
- 其他情况 → 不存在一笔画
2.3 图的存储与遍历
use std::collections::{HashMap, HashSet, VecDeque};
struct Graph {
adj: HashMap<i32, Vec<i32>>,
}
impl Graph {
fn new() -> Self { Graph { adj: HashMap::new() } }
fn add_edge(&mut self, u: i32, v: i32) {
self.adj.entry(u).or_default().push(v);
self.adj.entry(v).or_default().push(u);
}
// BFS 求最短路径
fn shortest_path(&self, start: i32, end: i32) -> Option<Vec<i32>> {
let mut visited = HashSet::new();
let mut queue = VecDeque::new();
let mut parent: HashMap<i32, i32> = HashMap::new();
visited.insert(start);
queue.push_back(start);
while let Some(node) = queue.pop_front() {
if node == end {
// 回溯路径
let mut path = Vec::new();
let mut current = end;
while current != start {
path.push(current);
current = parent[¤t];
}
path.push(start);
path.reverse();
return Some(path);
}
if let Some(neighbors) = self.adj.get(&node) {
for &neighbor in neighbors {
if !visited.contains(&neighbor) {
visited.insert(neighbor);
parent.insert(neighbor, node);
queue.push_back(neighbor);
}
}
}
}
None
}
}
fn main() {
let mut g = Graph::new();
g.add_edge(0, 1); g.add_edge(0, 2);
g.add_edge(1, 3); g.add_edge(2, 3);
g.add_edge(3, 4);
if let Some(path) = g.shortest_path(0, 4) {
println!("最短路径: {:?}", path); // [0, 1, 3, 4] 或 [0, 2, 3, 4]
}
}
2.4 图的应用
| 应用领域 | 具体应用 |
|---|---|
| 社交网络 | 好友关系、推荐系统 |
| 地图导航 | 最短路径(Dijkstra、A*) |
| 网络协议 | 路由算法、最小生成树 |
| 编译原理 | 语法树、依赖分析 |
| 密码学 | 零知识证明、区块链 |
三、数理逻辑
3.1 命题与逻辑联结词
命题:可以判断真假的陈述句。
| 联结词 | 符号 | Rust | 含义 |
|---|---|---|---|
| 非 | $\neg$ | ! | 取反 |
| 与 | $\land$ | && | 同真才真 |
| 或 | $\lor$ | || | 有真则真 |
| 蕴含 | $\rightarrow$ | — | 只有前真后假时为假 |
| 等价 | $\leftrightarrow$ | == | 同真同假 |
蕴含的真值表:
| $p$ | $q$ | $p \rightarrow q$ |
|---|---|---|
| T | T | T |
| T | F | F |
| F | T | T |
| F | F | T |
注意: $p \rightarrow q$ 等价于 $\neg p \lor q$。当前提为假时,蕴含式恒为真。
3.2 量词
| 量词 | 符号 | 含义 | 示例 |
|---|---|---|---|
| 全称量词 | $\forall$ | 对所有 | $\forall x > 0, x^2 > 0$ |
| 存在量词 | $\exists$ | 存在 | $\exists x, x^2 = 4$ |
量词的否定:
$$\neg(\forall x, P(x)) = \exists x, \neg P(x)$$
$$\neg(\exists x, P(x)) = \forall x, \neg P(x)$$
四、组合数学
4.1 加法原理与乘法原理
加法原理: 做一件事有 $n$ 类方法,第 $i$ 类有 $m_i$ 种方法,则总方法数为 $\sum m_i$。
乘法原理: 做一件事分 $n$ 步,第 $i$ 步有 $m_i$ 种方法,则总方法数为 $\prod m_i$。
4.2 排列与组合
$$P(n,m) = \frac{n!}{(n-m)!}$$
$$C(n,m) = \frac{n!}{m!(n-m)!}$$
4.3 鸽巢原理(抽屉原理)
将 $n+1$ 个物品放入 $n$ 个盒子中,至少有一个盒子包含至少 2 个物品。
推论: 367 人中至少两人生日相同(一年最多 366 天)。
4.4 容斥原理
$$|A \cup B| = |A| + |B| - |A \cap B|$$
$$|A \cup B \cup C| = |A| + |B| + |C| - |A \cap B| - |A \cap C| - |B \cap C| + |A \cap B \cap C|$$
五、关系
5.1 二元关系
从集合 $A$ 到集合 $B$ 的二元关系是 $A \times B$ 的子集。
5.2 关系的性质
| 性质 | 定义 |
|---|---|
| 自反性 | $\forall a, (a,a) \in R$ |
| 对称性 | $(a,b) \in R \Rightarrow (b,a) \in R$ |
| 传递性 | $(a,b) \in R \land (b,c) \in R \Rightarrow (a,c) \in R$ |
| 反对称性 | $(a,b) \in R \land (b,a) \in R \Rightarrow a = b$ |
5.3 等价关系
同时满足自反性、对称性、传递性的关系称为等价关系。
等价关系将集合划分为若干等价类,等价类的集合称为商集。
5.4 偏序关系
同时满足自反性、反对称性、传递性的关系称为偏序关系。
偏序关系可以用哈斯图(Hasse Diagram)直观表示。
六、代数结构
| 结构 | 定义 | 示例 |
|---|---|---|
| 半群 | 集合 + 满足结合律的运算 | 字符串拼接 |
| 群 | 半群 + 有单位元 + 有逆元 | 整数加法 $(\mathbb{Z}, +)$ |
| 环 | 群 + 第二种满足分配律的运算 | 整数环 $(\mathbb{Z}, +, \times)$ |
| 域 | 环 + 第二种运算有逆元 | 有理数域 $(\mathbb{Q}, +, \times)$ |
| 格 | 偏序集 + 任意两元素有上确界和下确界 | 子集格 $(\mathcal{P}(A), \subseteq)$ |
| 布尔代数 | 格 + 补运算 | 命题逻辑 |
应用: 群论是 RSA、ECC 等密码算法的数学基础。有限域上的运算支撑着 AES、椭圆曲线等加密体系。
七、学习资源
| 资源 | 说明 |
|---|---|
| 离散数学及其应用 (Rosen) | 经典教材 |
| VisuAlgo | 图论算法可视化 |
| 3Blue1Brown | 数学可视化 |
八、总结
| 分支 | 核心内容 |
|---|---|
| 集合论 | 并交差补、幂集、德摩根定律 |
| 图论 | 顶点、边、路径、树、欧拉路径 |
| 数理逻辑 | 命题、量词、蕴含、等价 |
| 组合数学 | 排列组合、鸽巢原理、容斥原理 |
| 关系 | 自反、对称、传递、等价关系、偏序关系 |
| 代数结构 | 群、环、域、格、布尔代数 |
离散数学是计算机科学的数学语言。从数据结构到算法设计,从数据库到密码学,离散数学的概念无处不在。
练习建议:
- 用 Rust 实现图的 DFS/BFS 遍历
- 用容斥原理解决计数问题
- 判断给定关系是否为等价关系或偏序关系