2离散数学及其应用(第8版)

基本结构

集合、函数、序列

集合论函数序列矩阵

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第2章 基本结构 (Basic Structures: Sets, Functions, Sequences)

一、导读

1.1 本章学习目标

完成本章学习后,你将能够:

理解集合的基本概念,包括集合的表示、子集、并集、交集、差集和补集

掌握集合运算的性质和恒等式,能够运用文氏图进行可视化分析

理解函数的定义、类型(单射、满射、双射)及其在计算机科学中的应用

掌握序列和求和的概念,能够计算常见序列的和

理解可数集与不可数集的区别,了解康托尔对角线论证法

掌握笛卡尔积的概念及其在关系数据库中的应用

理解基数和序数的基本概念

将集合论思维应用于数据结构设计和算法分析

1.2 为什么本章如此重要

集合、函数和序列是离散数学中最基本的结构,它们构成了计算机科学的理论基础。

集合论是所有数学的基础语言。在计算机科学中,集合用于描述数据类型、状态空间、语言(形式语言理论)、数据库关系等。理解集合运算是理解更高级概念的前提。

函数是编程的核心抽象。每个函数都建立了输入域到输出域的映射。理解函数的性质(如单射、满射、双射)对于设计哈希函数、加密算法、数据压缩等有重要意义。

序列是数组、列表、字符串等数据结构的基础。理解序列的性质有助于分析算法的时间复杂度,设计高效的搜索和排序算法。

在数据库领域:关系模型建立在集合论基础上,SQL操作本质上是集合运算。理解这些概念有助于编写更高效的查询。

在编程语言理论中:类型系统可以用集合来描述,函数类型对应集合间的映射,泛型涉及集合的参数化。

在算法分析中:时间复杂度和空间复杂度本质上是对序列增长率的描述。大O记号描述了函数在无穷远处的行为。

1.3 核心问题引导

在学习本章之前,请思考以下问题:

空集是什么?为什么空集是任何集合的子集?

集合 {1, 2, 3} 和 {3, 2, 1} 是否相同?为什么?

什么是幂集?一个有n个元素的集合有多少个子集?

如何判断两个无限集合的大小是否相同?

为什么有些无限集比另一些无限集"更大"?

函数 f(x) = x² 是否是单射?是否是满射?这取决于什么?

序列 1, 1/2, 1/4, 1/8, ... 的和是多少?

有理数集和整数集哪个更大?有理数集和实数集哪个更大?


二、核心概念详解

2.1 集合 (Sets)

定义与直觉解释

集合是不同对象的无序聚集。这些对象称为集合的元素或成员。

关键特性:

  • 无序性:{1, 2, 3} 和 {3, 1, 2} 是同一个集合
  • 互异性:集合中的元素不重复,{1, 1, 2} 等同于 {1, 2}
  • 确定性:对于任何对象,都能明确判断它是否属于该集合

集合的表示方法:

列举法:列出所有元素

- A = {1, 2, 3, 4, 5}

- B = {a, e, i, o, u}(英文元音字母)

描述法:用性质描述元素

- C = {x | x 是正偶数}

- D = {x ∈ ℝ | 0 ≤ x ≤ 1}

递归定义:通过规则生成元素

- 自然数集:0 ∈ ℕ;如果 n ∈ ℕ,则 n+1 ∈ ℕ

特殊集合:

  • 空集 ∅ 或 {}:不包含任何元素的集合
  • 全集 U:讨论范围内所有元素的集合
  • 自然数集 ℕ = {0, 1, 2, 3, ...}
  • 整数集 ℤ = {..., -2, -1, 0, 1, 2, ...}
  • 有理数集 ℚ = {p/q | p, q ∈ ℤ, q ≠ 0}
  • 实数集 ℝ:包括所有有理数和无理数

集合间的关系

子集:如果集合A的每个元素都是集合B的元素,则A是B的子集,记作 A ⊆ B。

形式化定义:A ⊆ B ⟺ ∀x (x ∈ A → x ∈ B)

真子集:如果 A ⊆ B 且 A ≠ B,则A是B的真子集,记作 A ⊂ B。

相等:A = B 当且仅当 A ⊆ B 且 B ⊆ A。即两个集合包含完全相同的元素。

重要定理:空集是任何集合的子集。

证明:要证明 ∅ ⊆ A,需要证明 ∀x (x ∈ ∅ → x ∈ A)。由于 x ∈ ∅ 永远为假,蕴含式 x ∈ ∅ → x ∈ A 永远为真(空真)。因此 ∅ ⊆ A。∎

集合运算

并集(Union):A ∪ B = {x | x ∈ A 或 x ∈ B}

交集(Intersection):A ∩ B = {x | x ∈ A 且 x ∈ B}

差集(Difference):A - B = {x | x ∈ A 且 x ∉ B},也记作 A \ B

补集(Complement):Ā = {x ∈ U | x ∉ A} = U - A

对称差(Symmetric Difference):A ⊕ B = (A - B) ∪ (B - A) = {x | x ∈ A 异或 x ∈ B}

示例:设 A = {1, 2, 3, 4}, B = {3, 4, 5, 6}

  • A ∪ B = {1, 2, 3, 4, 5, 6}
  • A ∩ B = {3, 4}
  • A - B = {1, 2}
  • B - A = {5, 6}
  • A ⊕ B = {1, 2, 5, 6}

幂集

集合A的幂集 P(A) 是A的所有子集构成的集合。

示例:P({1, 2}) = {∅, {1}, {2}, {1, 2}}

定理:如果集合A有n个元素,则 P(A) 有 2ⁿ 个元素。

证明:对于A中的每个元素,在构造子集时有两种选择:包含或不包含。由乘法原理,总共有 2 × 2 × ... × 2 = 2ⁿ 种选择,每种选择对应一个唯一的子集。∎

集合恒等式

恒等式公式
同一律A ∪ ∅ = A, A ∩ U = A
支配律A ∪ U = U, A ∩ ∅ = ∅
幂等律A ∪ A = A, A ∩ A = A
补集律A ∪ Ā = U, A ∩ Ā = ∅
交换律A ∪ B = B ∪ A, A ∩ B = B ∩ A
结合律(A ∪ B) ∪ C = A ∪ (B ∪ C)
分配律A ∪ (B ∩ C) = (A ∪ B) ∩ (A ∪ C)
德摩根律$\overline{A \cup B} = \bar{A} \cap \bar{B}$

德摩根定律的证明:

证明 $\overline{A \cup B} = \bar{A} \cap \bar{B}$:

x ∈ $\overline{A \cup B}$

⟺ x ∉ A ∪ B

⟺ ¬(x ∈ A 或 x ∈ B)

⟺ x ∉ A 且 x ∉ B(德摩根律在命题逻辑中)

⟺ x ∈ Ā 且 x ∈ B̄

⟺ x ∈ Ā ∩ B̄

因此 $\overline{A \cup B} = \bar{A} \cap \bar{B}$。∎

2.2 函数 (Functions)

定义与直觉解释

函数 f 从集合A到集合B是一个规则,它为A中的每个元素恰好指定B中的一个元素。

记作:f: A → B

  • 定义域(Domain):集合A
  • 陪域(Codomain):集合B
  • 值域(Range/Image):{f(a) | a ∈ A} ⊆ B

关键要求:

定义域中的每个元素都必须有像

每个元素的像是唯一的

示例:

  • f: ℤ → ℤ, f(x) = x²

- 定义域:ℤ

- 陪域:ℤ

- 值域:{0, 1, 4, 9, 16, ...}(非负完全平方数)

函数的类型

单射(Injective/One-to-one):不同的输入产生不同的输出。

形式化定义:∀x₁, x₂ ∈ A, f(x₁) = f(x₂) → x₁ = x₂

等价地:∀x₁, x₂ ∈ A, x₁ ≠ x₂ → f(x₁) ≠ f(x₂)

示例:f: ℤ → ℤ, f(x) = 2x 是单射。

反例:f: ℤ → ℤ, f(x) = x² 不是单射,因为 f(-1) = f(1) = 1。

满射(Surjective/Onto):值域等于陪域。

形式化定义:∀b ∈ B, ∃a ∈ A 使得 f(a) = b

示例:f: ℤ → ℤ, f(x) = x + 1 是满射。

反例:f: ℤ → ℤ, f(x) = x² 不是满射,因为没有整数的平方等于-1。

双射(Bijective/One-to-one correspondence):既是单射又是满射。

双射函数存在逆函数 f⁻¹: B → A。

示例:f: ℤ → ℤ, f(x) = x + 1 是双射,其逆函数为 f⁻¹(y) = y - 1。

函数的复合

给定 f: A → B 和 g: B → C,它们的复合 g ∘ f: A → C 定义为:

(g ∘ f)(x) = g(f(x))

性质:

  • 复合不满足交换律:一般 g ∘ f ≠ f ∘ g
  • 复合满足结合律:h ∘ (g ∘ f) = (h ∘ g) ∘ f

特殊函数

恒等函数:id_A: A → A, id_A(x) = x

地板函数(向下取整):⌊x⌋ = 不超过x的最大整数

天花板函数(向上取整):⌈x⌉ = 不小于x的最小整数

阶乘函数:n! = 1 × 2 × 3 × ... × n,其中 0! = 1

模函数:a mod n = a 除以 n 的余数

2.3 序列与求和 (Sequences and Summations)

序列的定义

序列是从正整数集(或非负整数集)到某个集合S的函数。序列的第n项记作 aₙ。

表示方法:

  • 列举法:1, 4, 9, 16, 25, ...
  • 通项公式:aₙ = n²
  • 递推关系:a₁ = 1, aₙ = aₙ₋₁ + 2n - 1

常见序列

算术序列:相邻项之差为常数d

  • 通项:aₙ = a + (n-1)d
  • 示例:2, 5, 8, 11, ...(a=2, d=3)

几何序列:相邻项之比为常数r

  • 通项:aₙ = arⁿ⁻¹
  • 示例:3, 6, 12, 24, ...(a=3, r=2)

斐波那契序列:

  • F₀ = 0, F₁ = 1
  • Fₙ = Fₙ₋₁ + Fₙ₋₂(n ≥ 2)
  • 序列:0, 1, 1, 2, 3, 5, 8, 13, 21, ...

调和序列:

  • aₙ = 1/n
  • 序列:1, 1/2, 1/3, 1/4, ...

求和

序列 a₁, a₂, ..., aₙ 的和记作:

$$\sum_{i=1}^{n} a_i = a_1 + a_2 + ... + a_n$$

常用求和公式:

求和公式
常数$\sum_{i=1}^{n} c = cn$
自然数$\sum_{i=1}^{n} i = \frac{n(n+1)}{2}$
平方和$\sum_{i=1}^{n} i^2 = \frac{n(n+1)(2n+1)}{6}$
立方和$\sum_{i=1}^{n} i^3 = \left[\frac{n(n+1)}{2}\right]^2$
几何级数$\sum_{i=0}^{n} r^i = \frac{r^{n+1}-1}{r-1}$(r ≠ 1)
无穷几何级数$\sum_{i=0}^{\infty} r^i = \frac{1}{1-r}$(r< 1)

几何级数求和公式的证明:

设 S = 1 + r + r² + ... + rⁿ

则 rS = r + r² + r³ + ... + rⁿ⁺¹

两式相减:S - rS = 1 - rⁿ⁺¹

即 S(1-r) = 1 - rⁿ⁺¹

因此 $S = \frac{1-r^{n+1}}{1-r} = \frac{r^{n+1}-1}{r-1}$ ∎

2.4 可数性 (Countability)

有限集与无限集

有限集:元素个数为自然数的集合。

无限集:不是有限集的集合。

基数

两个集合A和B有相同的基数(大小),如果存在从A到B的双射。

记作:|A| = |B|

有限集的基数:元素个数。

无限集的基数:

  • 可数无限:与自然数集ℕ有相同基数的集合,记作 ℵ₀(阿列夫零)
  • 不可数无限:基数大于 ℵ₀ 的集合

可数集

定理:正偶数集与ℕ有相同基数。

证明:定义 f: ℕ → {2, 4, 6, ...} 为 f(n) = 2n。这是双射。∎

这个结果令人惊讶:一个集合可以和它的真子集有相同的大小!这是无限集的特征。

定理:整数集ℤ是可数的。

证明:我们可以将整数排列为序列:0, 1, -1, 2, -2, 3, -3, ...

定义 f: ℕ → ℤ 为:

  • f(2k) = k
  • f(2k+1) = -(k+1)

这是双射。∎

定理:有理数集ℚ是可数的。

证明思路:将有理数排列成二维表格,然后按对角线遍历。虽然会有重复,但可以通过跳过已出现的数来获得双射。∎

不可数集

康托尔对角线论证:实数集ℝ是不可数的。

证明(针对[0,1]区间):

假设[0,1]区间的实数是可数的,可以将它们排列为序列 r₁, r₂, r₃, ...

将每个实数写成小数形式:

  • r₁ = 0.d₁₁ d₁₂ d₁₃ ...
  • r₂ = 0.d₂₁ d₂₂ d₂₃ ...
  • r₃ = 0.d₃₁ d₃₂ d₃₃ ...
  • ...

其中 dᵢⱼ 是第i个数的第j位小数。

构造一个新数 x = 0.x₁ x₂ x₃ ...,其中:

  • xᵢ = 5 如果 dᵢᵢ ≠ 5
  • xᵢ = 6 如果 dᵢᵢ = 5

x 与每个 rᵢ 至少在第i位不同,因此 x 不在列表中。这与列表包含所有[0,1]区间的实数矛盾。

因此[0,1]区间的实数是不可数的,从而ℝ也是不可数的。∎

连续统假设:不存在基数严格介于 ℵ₀ 和 |ℝ| 之间的集合。这个命题在标准集合论公理系统中既不能被证明也不能被证伪。

基数算术

对于无限基数,有以下性质:

  • ℵ₀ + ℵ₀ = ℵ₀
  • ℵ₀ × ℵ₀ = ℵ₀
  • 2^ℵ₀ = |ℝ|(连续统的基数)

三、程序员的视角

3.1 在计算机科学中的应用

数据结构

  • 集合:Python的set、Java的HashSet、C++的std::set
  • 字典/映射:实现函数概念的键值对结构
  • 数组/列表:序列的具体实现
  • 位向量:用位串表示有限集合,支持高效的集合运算

数据库

关系数据库基于集合论:

  • 表是元组的集合
  • SELECT 操作对应选择(筛选行)
  • PROJECT 操作对应投影(筛选列)
  • UNION、INTERSECT、EXCEPT 对应集合运算
  • JOIN 对应笛卡尔积的子集
sql
-- 并集
SELECT name FROM table1 UNION SELECT name FROM table2;

-- 交集
SELECT name FROM table1 INTERSECT SELECT name FROM table2;

-- 差集
SELECT name FROM table1 EXCEPT SELECT name FROM table2;

哈希函数

理想的哈希函数应该是单射(无冲突),但由于定义域通常大于陪域,这不可能实现。好的哈希函数应该尽量减少冲突。

复杂度分析

算法的时间复杂度描述了运行时间作为输入大小函数的增长率。大O记号本质上是描述函数集合:

O(f(n)) = {g(n) | ∃c > 0, ∃n₀, ∀n ≥ n₀, g(n) ≤ c·f(n)}

3.2 常见陷阱与误区

混淆 ∈ 和 ⊆

  • ∈ 表示元素与集合的关系:1 ∈ {1, 2, 3}
  • ⊆ 表示集合与集合的关系:{1} ⊆ {1, 2, 3}

注意:1 ⊆ {1, 2, 3} 是错误的写法。

空集的微妙性

  • ∅ 是任何集合的子集
  • {∅} 不是空集,它是一个包含一个元素(空集)的集合
  • ∅ ∈ {∅} 为真,但 ∅ ∈ ∅ 为假

函数定义的完整性

在编程中,忘记处理某些输入情况会导致运行时错误。确保函数对定义域中的所有输入都有定义。

python
# 错误:未处理 x = 0 的情况
def reciprocal(x):
    return 1 / x

# 正确:处理边界情况
def safe_reciprocal(x):
    if x == 0:
        raise ValueError("Cannot compute reciprocal of zero")
    return 1 / x

浮点数精度

实数在计算机中只能用有限精度的浮点数近似。这导致:

  • 0.1 + 0.2 ≠ 0.3(精确相等)
  • 累加大量小数时误差会累积

3.3 与其他层级的联系

  • 硬件层:位运算直接对应集合运算(位向量表示集合)
  • 操作系统层:文件权限集合、进程组
  • 网络层:IP地址集合、路由表
  • 应用层:用户组、标签系统、推荐系统的候选集

四、代码实战

4.1 集合运算实现

python
"""
集合运算的实现与演示
使用Python内置set类型,但展示底层原理
"""

class SetOperations:
    """集合运算工具类"""
    
    @staticmethod
    def union(set_a, set_b):
        """并集:A ∪ B"""
        result = set(set_a)  # 复制A
        result.update(set_b)  # 添加B的元素
        return result
    
    @staticmethod
    def intersection(set_a, set_b):
        """交集:A ∩ B"""
        result = set()
        for elem in set_a:
            if elem in set_b:
                result.add(elem)
        return result
    
    @staticmethod
    def difference(set_a, set_b):
        """差集:A - B"""
        result = set()
        for elem in set_a:
            if elem not in set_b:
                result.add(elem)
        return result
    
    @staticmethod
    def symmetric_difference(set_a, set_b):
        """对称差:A ⊕ B"""
        return SetOperations.difference(
            SetOperations.union(set_a, set_b),
            SetOperations.intersection(set_a, set_b)
        )
    
    @staticmethod
    def is_subset(subset, superset):
        """判断是否为子集:subset ⊆ superset"""
        for elem in subset:
            if elem not in superset:
                return False
        return True
    
    @staticmethod
    def power_set(original_set):
        """幂集:P(A),返回所有子集的列表"""
        elements = list(original_set)
        n = len(elements)
        result = []
        
        # 使用位掩码枚举所有子集
        for mask in range(2 ** n):
            subset = set()
            for i in range(n):
                if mask & (1 << i):
                    subset.add(elements[i])
            result.append(subset)
        
        return result
    
    @staticmethod
    def cartesian_product(set_a, set_b):
        """笛卡尔积:A × B"""
        result = set()
        for a in set_a:
            for b in set_b:
                result.add((a, b))
        return result


def demonstrate_set_operations():
    """演示集合运算"""
    A = {1, 2, 3, 4, 5}
    B = {4, 5, 6, 7, 8}
    
    print(f"A = {A}")
    print(f"B = {B}")
    print(f"A ∪ B = {SetOperations.union(A, B)}")
    print(f"A ∩ B = {SetOperations.intersection(A, B)}")
    print(f"A - B = {SetOperations.difference(A, B)}")
    print(f"B - A = {SetOperations.difference(B, A)}")
    print(f"A ⊕ B = {SetOperations.symmetric_difference(A, B)}")
    print(f"A ⊆ B? {SetOperations.is_subset(A, B)}")
    print(f"{{1, 2}} ⊆ A? {SetOperations.is_subset({1, 2}, A)}")
    
    print("\n幂集 P({{1, 2, 3}}):")
    for subset in SetOperations.power_set({1, 2, 3}):
        print(f"  {subset}")
    
    print(f"\n笛卡尔积 {{1, 2}} × {{'a', 'b'}}:")
    for pair in SetOperations.cartesian_product({1, 2}, {'a', 'b'}):
        print(f"  {pair}")


if __name__ == "__main__":
    demonstrate_set_operations()

4.2 函数性质检查

python
"""
检查函数的单射性、满射性和双射性
"""

def is_injective(func, domain, codomain):
    """
    检查函数是否为单射
    
    参数:
        func: 函数,接受domain中的元素,返回codomain中的元素
        domain: 定义域(可迭代对象)
        codomain: 陪域(可迭代对象)
    
    返回:
        bool: 是否为单射
    """
    images = []
    for x in domain:
        fx = func(x)
        if fx in images:
            return False  # 找到两个不同元素映射到同一值
        images.append(fx)
    return True


def is_surjective(func, domain, codomain):
    """
    检查函数是否为满射
    
    参数:
        func: 函数
        domain: 定义域
        codomain: 陪域
    
    返回:
        bool: 是否为满射
    """
    codomain_set = set(codomain)
    image_set = set(func(x) for x in domain)
    return codomain_set.issubset(image_set)


def is_bijective(func, domain, codomain):
    """检查函数是否为双射"""
    return is_injective(func, domain, codomain) and \
           is_surjective(func, domain, codomain)


def find_inverse(func, domain, codomain):
    """
    寻找双射函数的逆函数
    
    返回:
        dict: 逆映射,或None如果函数不是双射
    """
    if not is_bijective(func, domain, codomain):
        return None
    
    inverse = {}
    for x in domain:
        inverse[func(x)] = x
    return inverse


def demonstrate_function_properties():
    """演示函数性质检查"""
    
    # 示例1: f(x) = 2x, 从 {1,2,3} 到 {2,4,6,8}
    domain1 = [1, 2, 3]
    codomain1 = [2, 4, 6, 8]
    func1 = lambda x: 2 * x
    
    print("函数 f(x) = 2x, 定义域={1,2,3}, 陪域={2,4,6,8}")
    print(f"  单射: {is_injective(func1, domain1, codomain1)}")
    print(f"  满射: {is_surjective(func1, domain1, codomain1)}")
    print(f"  双射: {is_bijective(func1, domain1, codomain1)}")
    
    # 示例2: f(x) = x^2, 从 {-2,-1,0,1,2} 到 {0,1,2,3,4}
    domain2 = [-2, -1, 0, 1, 2]
    codomain2 = [0, 1, 2, 3, 4]
    func2 = lambda x: x ** 2
    
    print("\n函数 f(x) = x², 定义域={-2,-1,0,1,2}, 陪域={0,1,2,3,4}")
    print(f"  单射: {is_injective(func2, domain2, codomain2)}")
    print(f"  满射: {is_surjective(func2, domain2, codomain2)}")
    print(f"  双射: {is_bijective(func2, domain2, codomain2)}")
    
    # 示例3: f(x) = x + 1, 从 {0,1,2} 到 {1,2,3}
    domain3 = [0, 1, 2]
    codomain3 = [1, 2, 3]
    func3 = lambda x: x + 1
    
    print("\n函数 f(x) = x+1, 定义域={0,1,2}, 陪域={1,2,3}")
    print(f"  单射: {is_injective(func3, domain3, codomain3)}")
    print(f"  满射: {is_surjective(func3, domain3, codomain3)}")
    print(f"  双射: {is_bijective(func3, domain3, codomain3)}")
    
    inverse = find_inverse(func3, domain3, codomain3)
    if inverse:
        print(f"  逆函数: {inverse}")


if __name__ == "__main__":
    demonstrate_function_properties()

4.3 序列求和与收敛性

python
"""
序列求和与收敛性分析
"""

import math


def arithmetic_sum(a, d, n):
    """
    算术序列求和
    
    参数:
        a: 首项
        d: 公差
        n: 项数
    
    返回:
        float: 前n项和
    """
    return n * (2 * a + (n - 1) * d) / 2


def geometric_sum(a, r, n):
    """
    几何序列求和
    
    参数:
        a: 首项
        r: 公比
        n: 项数
    
    返回:
        float: 前n项和
    """
    if r == 1:
        return a * n
    return a * (1 - r ** n) / (1 - r)


def infinite_geometric_sum(a, r):
    """
    无穷几何级数求和(仅当|r| < 1时收敛)
    
    参数:
        a: 首项
        r: 公比
    
    返回:
        float or None: 和,如果不收敛则返回None
    """
    if abs(r) >= 1:
        return None
    return a / (1 - r)


def harmonic_sum(n):
    """
    调和序列求和
    
    参数:
        n: 项数
    
    返回:
        float: 前n项和
    """
    return sum(1.0 / i for i in range(1, n + 1))


def fibonacci_sequence(n):
    """
    生成斐波那契序列的前n项
    
    参数:
        n: 项数
    
    返回:
        list: 斐波那契数列
    """
    if n <= 0:
        return []
    if n == 1:
        return [0]
    
    fib = [0, 1]
    for i in range(2, n):
        fib.append(fib[-1] + fib[-2])
    return fib


def demonstrate_sequences():
    """演示序列求和"""
    
    # 算术序列: 2, 5, 8, 11, ...
    print("算术序列: 2, 5, 8, 11, ...")
    print(f"  前10项和: {arithmetic_sum(2, 3, 10)}")
    print(f"  验证: {sum(2 + 3*i for i in range(10))}")
    
    # 几何序列: 3, 6, 12, 24, ...
    print("\n几何序列: 3, 6, 12, 24, ...")
    print(f"  前10项和: {geometric_sum(3, 2, 10)}")
    print(f"  验证: {sum(3 * 2**i for i in range(10))}")
    
    # 无穷几何级数: 1 + 1/2 + 1/4 + 1/8 + ...
    print("\n无穷几何级数: 1 + 1/2 + 1/4 + 1/8 + ...")
    print(f"  理论和: {infinite_geometric_sum(1, 0.5)}")
    print(f"  前20项和: {geometric_sum(1, 0.5, 20)}")
    
    # 调和序列
    print("\n调和序列: 1 + 1/2 + 1/3 + 1/4 + ...")
    for n in [10, 100, 1000, 10000]:
        print(f"  前{n}项和: {harmonic_sum(n):.6f}")
    print("  注意: 调和级数发散(趋向无穷)")
    
    # 斐波那契序列
    print("\n斐波那契序列:")
    fib = fibonacci_sequence(15)
    print(f"  前15项: {fib}")
    print(f"  前15项和: {sum(fib)}")
    
    # 黄金比例与斐波那契
    print("\n斐波那契比值趋近黄金比例:")
    for i in range(2, 15):
        ratio = fib[i] / fib[i-1] if fib[i-1] != 0 else float('inf')
        print(f"  F({i})/F({i-1}) = {fib[i]}/{fib[i-1]} ≈ {ratio:.6f}")
    print(f"  黄金比例 φ = {(1 + math.sqrt(5)) / 2:.6f}")


if __name__ == "__main__":
    demonstrate_sequences()

五、深入思考

5.1 历史背景

集合论由德国数学家格奥尔格·康托尔(Georg Cantor, 1845-1918)在19世纪末创立。他的工作在当时引起巨大争议,因为无限集的性质违反直觉。然而,集合论最终成为现代数学的基础。

罗素悖论(1901年)揭示了朴素集合论的问题:考虑集合 R = {x | x ∉ x},那么 R ∈ R 吗?如果 R ∈ R,则根据定义 R ∉ R;如果 R ∉ R,则 R 应该属于 R。这个悖论促使数学家发展公理化集合论(如ZFC公理系统)来避免此类矛盾。

5.2 前沿方向

  • 范畴论:提供比集合论更抽象的数学基础,在函数式编程中有应用
  • 同伦类型论:结合类型论和同伦论的新兴基础理论
  • 计算集合论:研究集合运算的高效算法
  • 模糊集合:允许元素以某种程度属于集合,在人工智能中有应用

5.3 延伸阅读

  • 《Naive Set Theory》by Paul R. Halmos
  • 《Introduction to Set Theory》by Karel Hrbacek and Thomas Jech
  • 《Concrete Mathematics》by Graham, Knuth, Patashnik

六、实验笔记

实验1:集合运算可视化

目标:实现一个能够绘制文氏图并执行集合运算的程序。

任务:

设计数据结构表示有限集合

实现所有基本集合运算(并、交、差、对称差、补集)

使用图形库(如matplotlib)绘制两个或三个集合的文氏图

在文氏图上高亮显示运算结果

验证集合恒等式(如德摩根定律)

测试用例:

  • A = {1, 2, 3, 4}, B = {3, 4, 5, 6}
  • 验证 A ∪ (B ∩ C) = (A ∪ B) ∩ (A ∪ C)

提交物:源代码、文氏图输出、验证报告。

实验2:可数性探索

目标:通过编程探索可数集的性质。

任务:

实现整数集到自然数集的双射

实现有理数的枚举(按对角线遍历)

验证康托尔配对函数:π(k₁, k₂) = (k₁ + k₂)(k₁ + k₂ + 1)/2 + k₂ 是 ℕ×ℕ 到 ℕ 的双射

尝试实现实数的近似表示,观察精度限制

(进阶)实现康托尔对角线论证的模拟

提交物:源代码、枚举结果、分析报告。


七、本章小结

本章介绍了离散数学的三个基本结构:集合、函数和序列。

集合是无序元素的聚集,集合运算包括并、交、差、补等。幂集包含所有子集,其大小是原集合大小的2的幂次。集合恒等式(如德摩根定律)在逻辑推理和电路设计中都有应用。

函数建立从一个集合到另一个集合的映射。单射保证不同输入产生不同输出,满射保证陪域中每个元素都有原像,双射同时满足两者且存在逆函数。函数的复合不满足交换律但满足结合律。

序列是有序的元素列表,可以是有限的或无限的。常见的序列包括算术序列、几何序列和斐波那契序列。求和公式使我们能够快速计算序列的和,而无需逐项相加。

可数性揭示了无限集的奇妙性质:有些无限集(如整数、有理数)是可数的,可以与自然数建立一一对应;而另一些无限集(如实数)是不可数的,严格大于可数无限。康托尔对角线论证是证明不可数性的经典方法。

这些基本概念为后续章节(关系、图、树等)奠定了基础,也是理解计算机科学核心理论的关键。


八、习题

习题1(基础):设 A = {1, 2, 3, 4, 5}, B = {3, 4, 5, 6, 7}, C = {5, 6, 7, 8, 9}。计算:

(a) A ∪ B

(b) A ∩ (B ∪ C)

(c) (A - B) ∪ (B - A)

(d) P(A) 的大小

习题2(基础):判断下列陈述的真假:

(a) ∅ ∈ {∅}

(b) ∅ ⊆ {∅}

(c) {∅} ⊆ ∅

(d) {{∅}} ⊆ {∅, {∅}}

习题3(中等):证明以下集合恒等式:

(a) A ∩ (B ∪ C) = (A ∩ B) ∪ (A ∩ C)

(b) A - (B ∪ C) = (A - B) ∩ (A - C)

(c) (A - B) - C = A - (B ∪ C)

习题4(中等):确定下列函数是否为单射、满射、双射:

(a) f: ℤ → ℤ, f(x) = x - 1

(b) f: ℤ → ℤ, f(x) = x² + 1

(c) f: ℤ⁺ → ℤ⁺, f(x) = x + 1

(d) f: ℝ → ℝ, f(x) = 2x - 3

习题5(中等):求下列和:

(a) $\sum_{i=1}^{100} (2i - 1)$

(b) $\sum_{i=0}^{10} 3 \cdot 2^i$

(c) $\sum_{i=1}^{n} i(i+1)$

习题6(较难):证明有理数集ℚ是可数的。(提示:将正有理数排列成二维表格,按对角线遍历)

习题7(较难):证明开区间(0, 1)与实数集ℝ有相同的基数。(提示:构造一个双射,如使用正切函数的变换)

习题8(挑战):施罗德-伯恩斯坦定理:如果存在单射 f: A → B 和单射 g: B → A,则存在双射 h: A → B。尝试证明这个定理或给出直观解释。

习题9(挑战):证明对于任何集合A,|A| < |P(A)|。(提示:假设存在双射,使用类似康托尔对角线的方法导出矛盾)

习题10(开放):研究并报告一个在实际应用中使用的特殊函数(如哈希函数、加密函数、激活函数等),分析其数学性质(是否为单射、满射、双射?)。

2/13基本结构
0%