MIT-6-042J-计算机科学的数学基础笔记-全-

MIT 6.042J 计算机科学的数学基础笔记(全)

MIT 6.042J 计算机科学的数学基础:P1:L1.1.1 - 欢迎来到 6.042 📚

在本节课中,我们将要学* MIT 6.042J 课程《计算机科学的数学基础》的导论部分。我们将了解这门课程的核心内容、授课教师以及它为何对计算机科学家至关重要。

欢迎导师是亚当·查拉教授和阿尔伯特·梅尔教授。

我是艾伯特,你好。

课程内容概述

接下来,让我们快速总结本课程的内容。这门课程是关于计算机科学家几乎都经常需要的数学。这是你在标准微积分课上不太可能遇到的数学知识。

你可能在高中见过一些类似的内容。例如,在微积分课程中,人们谈论实数上的函数。有时他们会谈论复数上的函数。

但是,计算机科学家通常处理数据类型上更抽象的函数,甚至处理函数上的函数。我想知道你们中有多少人,如果我让你抽象地定义什么是函数,可以在几周内在这门课上给出这个定义。

你可以很方便地做那件事。

核心数学结构

上一节我们介绍了课程的整体方向,本节中我们来看看将要讨论的核心数学结构。

我们将讨论各种标准离散结构。我们从数字开始。我们认为数字是一个结构,因为它是包装在上面的操作的数字,就像加号、乘法和幂。

我们还将讨论各种其他标准图形数据结构,像图形和树。

计算方法与应用

了解了核心结构后,我们来看看如何应用它们。我们将研究计算这些数字的方法,以及不同类型的数据结构。

作为计算机科学中一个典型的基础问题,您通常想知道搜索空间有多大。比如说,密码的搜索空间最好大,或者一个程序可以把它们都搜索一遍,找到一个有效的。

离散概率论

最后,我们将讨论离散概率论。这只是概率论的一个版本,在那里我们可以用和来度过,而不是进入积分的复杂性。

关键概念检查

在结束之前,让我们做一个快速的概念检查。你知道“离散”是什么意思吗?我会给你一个提示,这并不意味着“谨慎”。如果你不知道,不用担心,我们将在课程中详细学*。


本节课中,我们一起学*了 MIT 6.042J 课程的欢迎导论。我们了解了课程将由亚当·查拉教授和阿尔伯特·梅尔教授授课,并概述了课程将涵盖的核心内容:包括抽象函数、离散结构(如数字、图、树)、相关的计算方法以及离散概率论。这些数学工具是计算机科学领域不可或缺的基础。

计算机科学的数学基础:P2:L1.1.2:证明入门 - 第一部分 🧮

在本节课中,我们将要学*数学证明的基本概念。我们将通过一个著名的例子——毕达哥拉斯定理——来理解什么是证明,以及为什么严谨的证明在数学和计算机科学中至关重要。我们还将探讨直观的“图示证明”可能存在的陷阱。


证明的重要性

上一节我们介绍了课程的整体目标。本节中,我们来看看证明的核心价值。

在数学和理论计算机科学中,我们非常关心证明。我们会帮助你学*如何进行基本的证明,无需畏惧它们。在某些方面,最重要的技能是区分“看似非常合理的论点”与“完全正确的证明”的能力。这二者可能不完全相同,而这项区分能力是一项重要的技能。

这是对数学本质的基本理解。这关乎于知道一件事在数学上是绝对无可争辩的,而不仅仅是极有可能。有趣的是,物理学家做了大量的数学工作,但他们往往不太担心证明的绝对严谨性。

然而,所有的理论家和数学家都同意:除非你知道如何证明基本事实,否则你并未真正理解这个主题。从务实的角度看,证明的价值在于,本主题(以及许多其他数学科目)内容繁多。如果了解确切细节的唯一方法是死记硬背,你很容易迷失方向。

我们证明的大多数规则和定理,我无法全部记住细节,但我知道如何证明它们。这样,我就可以在需要时推导、调试它们,并确保其完全正确。


一个经典例子:毕达哥拉斯定理

在开始抽象地讨论证明之前,让我们先看一些具体的证明例子。

你们在高中早期就见过一个著名定理:毕达哥拉斯定理。它指出,对于一个边长为 ab 的直角三角形,其斜边 c 满足以下关系:

a² + b² = c²

正如我所说,这个定理广为人知。它“明显”吗?有时学生会说它明显,但我想他们真正的意思是“很熟悉”。它其实并不明显。几千年来,人们一直觉得有必要证明它,以确定其真实性并解释其原因。有一个专门收集毕达哥拉斯定理证明的网站,上面收录了一百多种证明,甚至包括美国前总统提供的一种。


一个优雅的图示证明

让我们看看我最喜欢的毕达哥拉斯定理证明之一。证明思路如下:

我们有四个全等的直角三角形(ABC 三角形的四个副本,用不同颜色区分)和一个大小未知的正方形。

毕达哥拉斯定理的证明,将包括把这四种形状重新组合成两种不同的图形:

  1. 第一种组合形成一个边长为 c 的大正方形(c × c)。
  2. 第二种组合形成两个正方形,分别是 a × ab × b

然后,根据面积守恒定律,c × c 的面积必须等于 a × ab × b 的面积。因此,a² + b² = c² 成立。

让我们看看这些重新排列。也许你应该在我给出解答之前,花点时间自己尝试一下。


第一种排列:形成 c × c 正方形

第一种排列是两者中较容易的一个,目标是形成边长为 c 的正方形。提示是:如果想得到 c × c 的正方形,除了将三角形的斜边 c 放在外围,你没有太多选择。通过摆弄三角形的位置使其贴合,你会发现中间恰好空出了一个正方形,这正是我们额外准备的那个小正方形所适合的位置。

这个排列也让你能够计算出中间小正方形的尺寸。观察图形,这是三角形的长边 b,这是短边 a,所以中间空出的边长是 b - a。因此,我们知道中间是一个 (b - a) × (b - a) 的正方形。


第二种排列:形成 正方形

下一个排列是这样的:我们要将其中两个三角形拼成一个矩形,另外两个三角形拼成另一个矩形,并按特定方式对齐,同时放入那个 (b - a) × (b - a) 的小正方形。

那么 a × ab × b 的正方形在哪里?它们并没有以独立的大方块出现,但隐含在图形中。让我们观察这条边的长度:它是 a + (b - a),这意味着它的长度是 b。这里突然出现了一个长度为 b 的边。

但是等等,这里有一段是 b - a,它正对着 b 边。所以,如果我观察剩余的部分:b - (b - a),这告诉我那一小段的长度是 a。果然,当我添加一条概念上的分割线时,这部分是 a × a 的正方形,那部分是 b × b 的正方形。


对图示证明的思考

我们就这样“证明”了毕达哥拉斯定理。那么这个证明如何?它非常优雅,并且看起来绝对正确。这是一个很好的“图示证明”案例,在这种情况下确实有效。

但不幸的是,这类证明让数学家感到担忧。他们的担忧是合理的,因为其中隐藏了许多假设和未经陈述的推理步骤。你需要回溯并思考所有隐含的几何信息。

在这张图中,很多东西被认为是理所当然的。例如:

  • 我们怎么知道那个角是直角?我们声称中间是一个正方形,这需要它是直角。
  • 我们怎么知道那是一个矩形?我们利用了“直角三角形两锐角互余”以及“三角形内角和为180度”等事实。
  • 我们还利用了“这是一条直线”的事实,这可能很明显,也可能不明显,但正是这一点保证了长度相加是可行的。

我的观点是:图示中真的有很多隐藏的假设,很容易被忽视,从而可能导致错误。


图示证明的陷阱:一个反例

为了展示被图示证明愚弄的例子,让我们看看如何“获得”无限的财富。

想象我有一张 10 × 11 的金箔(一个矩形,四个角都是直角)。我要做的是:在左上角,沿着边量出长度1并剪下一个小三角形;在右下角,也做同样操作。然后,我将这两个剪下的三角形移动位置,一个移到左上方,一个移到右下方。

最终我得到了一个新的形状。现在,这条边的长度是 10(因为从原长度中减去了1),这条边的长度是 11(因为给原长度加上了1)。这看起来很酷,因为现在我可以把那些突出的小三角形剪下来,它们恰好能拼成一个 1 × 1 的小正方形。

突然间,我多出了一小块金子!但再看这里:我剩下的部分,不又是一个 10 × 11 的长方形金箔吗?我可以把它旋转90度,重复这个过程。这样我就可以不断地生成 1 × 1 的小金块,变得无限富有!

这显然有问题。它违反了各种守恒定律,更会摧毁黄金市场。问题出在哪里?

关键在于一个隐含的假设:我声称剪下的那些小三角形是直角三角形,并且移动后形成的这条长边是一条完美的直线。实际上,那些三角形有两条长度为1的边,是等腰三角形,但它们放置的对角线角度并非45度,因此它们不是直角三角形。这条“边”实际上不是一条直线。由于 1011 很接*,这在视觉上并不明显。

这就是一个简单的例子,展示了图示证明如何可能误导我们。如果我被要求证明“这是一条直线”,这个漏洞就会暴露出来。但如果它在视觉上不明显,你很可能不会注意到。


本节课总结

在本节课中,我们一起学*了:

  1. 证明的核心价值:在于区分合理论点与严谨证明,是理解数学主题的基础。
  2. 通过例子学*:以毕达哥拉斯定理为例,分析了一个优雅的图示证明。
  3. 认识图示证明的局限性:图示可能隐藏许多几何假设,依赖视觉直观可能导致错误。
  4. 警惕陷阱:通过一个“无限财富”的反例,我们看到了不严谨的图示推理如何产生荒谬的结论。

理解证明的严谨性,是迈向数学和理论计算机科学深处的重要一步。在接下来的课程中,我们将学*更形式化、更可靠的证明方法。

计算机科学的数学基础:P3:L1.1.3 - 证明入门 - 第二部分 🔍

概述

在本节课中,我们将继续探讨证明方法,重点关注一个关于多项式求根的“伪证明”案例。我们将分析这个证明中的逻辑漏洞,并理解为何盲目依赖公式计算可能导致错误结论。通过这个例子,我们将学*在数学证明中保持严谨和清晰理解的重要性。


上一节我们介绍了证明的基本概念和常见错误类型。本节中,我们来看看一个关于多项式根的典型错误证明案例。

还有其他类型的伪证明。让我们快速浏览一个关于多项式根的证明。你知道一个事实:每个多项式至少有两个根(在复数域C上)。你怎么证明这一点?你只需写下求根公式。你知道二次公式:一个根是 (-b + sqrt(b^2 - 4ac)) / (2a)

另一个根是 (-b - sqrt(b^2 - 4ac)) / (2a)。证明到此结束。你可以把这个公式代入 r1 到多项式 x 中,它将简化为零,说明这是一个根。你可以把 x 的这个公式代入,简化代数运算,发现它等于零。这就证明了 r2 也是一个根。

我们刚刚“证明”了每个多项式都有两个根。但这不是真的。我们还没有完成证明。这是一个有问题的计算证明。

有什么问题?让我们看一个反例。多项式 0*x^2 + 0*x + 1 没有任何根。它只是一个常数,永远不会等于零,所以它没有根。多项式 0*x^2 + 1*x + 0 是一条45度的线 y = x,它只穿过原点一次,所以它只有一个根。

那么,两个公式 r1r2 怎么了?答案是,在这种情况下,我们必须除以零,这是错误的。如果你看那个公式,分母是 2a。除以零导致这些公式不正确,它们不是根。因此,为了有两个根,我们需要隐含地假设分母 a(多项式的首项系数)不为零。

这样就修复了这两个漏洞吗?不。

因为看这个多项式 1*x^2 + 0*x + 0。它只有一个根。唯一可能的方式是,如果某物的*方加零等于零,那么该物必须为零,所以只有一个根。这里发生了什么?发生的事情是,在这种情况下,两个公式 r1r2 是对同一事物的不同表述。当 b=0c=0a=1 时,这就是为什么它们看起来像不同的公式,但它们的值是一样的。所以只有一个根。公式 r1r2 不是零。这就是你取判别式 D = b^2 - 4ac 的*方根需要为零的情况,这样我们才会得到两个相同的根。

现在还有一个复杂的问题。听起来我们现在已经修正了我们的计算证明,加入了这些限定条件:a 不为零,且判别式 D 非零。但是如果 D 不为零但是负数,会发生什么呢?这是一个有趣的复杂情况。

让我们看看多项式 x^2 + 1b^2 - 4ac-4。这将有两个根,即 i-i。不可能分辨出哪个是 r1,哪个是 r2r1sqrt(-1)r2-sqrt(-1)。但 sqrt(-1) 没有办法区分是 i 还是 -i。抽象地说,它们的行为方式是一样的。所以我们对哪个是 r1、哪个是 r2 存在歧义。这本身并不影响“有两个根”的定理。

但这种歧义可能会带来问题。让我给你们一个例子。当存在这种歧义时,我可以“证明” 1 = -1。这是证明过程。我会让你好好想想,试着弄清楚这个推理中哪一步出了问题。步骤似乎很合理,但尽管如此,我得出了 1 等于 -1 的荒谬结论。它在利用你不知道 sqrt(-1) 是指 i 还是 -i 这一事实。

所以这一切的寓意是:首先,确保你正确地应用了规则。这里有一个关于代数规则的隐含假设是不正确的。同样,当你并不真正明白自己在做什么、不清楚确切的规则是什么时,这种盲目的计算是有风险的。是理解把你从这种错误中解救出来。

让我们稍微看一下 1 = -1 的“证明”,因为它让我们用一句有趣的话来结束。1 等于 -1 的可怕之处在于它是错误的。你永远不想得出错误的结论。这令人担忧。当你断定某件事是假的时,那是灾难性的。

让我给你一个例子。假设 1 等于 -1 是正确的(基于我们错误证明的假设)。如果我把方程的两边乘以相同的东西,等式仍然成立。所以我可以把两边都乘以 1/2,我得到 1/2 = -1/2。现在我也可以把同样的东西加到两边,这是对等式进行推理的一个非常合理的规则。如果我把两边都加上 3/2,我把 1 = -1 变成了 2 = 1

现在,我的状态很好,可以“证明”各种各样的事情。这里有一个著名的例子:因为我和教皇显然也是(基于 2=1),我们得出结论,我和教皇是一体的,那就是“我是教皇”。我刚刚向你“证明”了这个荒谬的事实。

这是一个被归因于伯特兰·罗素(著名的哲学家、逻辑学家、和*主义者、诺贝尔奖得主)的妙语。据说派对上的某个社交名媛找到了他,她听说数学家们认为如果 1 等于 -1,那你就可以证明任何事情。所以她挑战他证明“你是教皇”。据说是罗素(他以机智著称)想出了这个例子。谁知道这是不是真的,但这是个好故事。

有一张伟人的照片。


总结

本节课中,我们一起学*了一个关于多项式根的伪证明案例。我们分析了其中因忽略公式适用条件(如 a ≠ 0)、未考虑判别式为零或为负的情况以及符号歧义而导致的逻辑错误。这个例子深刻地提醒我们,数学证明不能仅仅依赖公式计算,而必须建立在清晰的理解和严谨的逻辑基础之上。理解规则背后的假设和限制,是避免得出荒谬结论的关键。

计算机科学的数学基础:P4:L1.2.1:矛盾证明法 🔍

在本节课中,我们将要学*一种在数学和计算机科学中至关重要的证明技术——矛盾证明法。我们将通过具体的例子来理解其工作原理,并学*如何应用它来证明一些基本但深刻的数学事实。

概述

证明是数学和计算机科学的核心。如果你无法解释某个陈述为何为真,那么你对它的理解就值得怀疑。矛盾证明法是一种通过假设结论不成立,并推导出逻辑矛盾,从而证明原结论必然成立的推理方法。这种方法非常强大,有时能让我们在不直接计算的情况下证明某些命题。

一个简单的例子

上一节我们介绍了证明的重要性,本节中我们来看看矛盾证明法是如何运作的。让我们从一个简单的例子开始。

假设我们想判断 1332的立方根 是否小于或等于 11。一种直接的方法是计算立方根,但这可能有些繁琐。我们可以尝试使用矛盾证明法。

首先,我们假设结论成立,即:
立方根(1332) ≤ 11

如果这个假设为真,那么我们可以对不等式两边同时进行立方运算(因为立方运算是单调递增的),得到:
1332 ≤ 11³

计算 11³ = 1331。因此,我们的假设导出了:
1332 ≤ 1331

这个结论 显然是错误的。这意味着我们最初的假设 立方根(1332) ≤ 11 导致了矛盾。因此,这个假设本身必然是假的。由此,我们证明了:
立方根(1332) > 11

我们并没有实际计算1332的立方根,但通过逻辑推理,明确地得出了这个结论。这个例子清晰地展示了矛盾证明法的基本思想:如果一个断言(假设)蕴含了错误的东西,那么这个断言本身一定是假的。

矛盾证明法的原理

如果一个断言通过一系列有效的推理步骤,最终推导出了一个错误的结论,那么唯一合理的解释就是:最初的断言是假的。这是因为,有效的推理会保持“真值”——如果你从真命题出发,经过有效推理,得到的结论也必然为真。反之,如果结论为假,那么前提必然为假。

一个经典的证明:√2 是无理数

现在,让我们运用矛盾证明法来解决一个著名的数学问题:证明 2的*方根(√2)是无理数。首先,我们需要明确,有理数是可以表示为两个整数之商(分数)的数,且分子分母没有大于1的公因数(即已化为最简形式)。

我们要证明:√2 不是有理数

证明过程如下:

  1. 首先,做出相反的假设:假设 √2 是有理数。那么,存在两个互质的整数 nd(即它们没有共同的素因子),使得:
    √2 = n / d

  2. 从这个假设出发进行推导

    • 将等式两边同时乘以 d,得到:√2 * d = n
    • 再将等式两边同时*方,以消去根号:2 * d² = n²
    • 观察这个等式:左边 2 * d² 能被 2 整除,因此右边 也必然能被 2 整除,即 是偶数。
  3. 一个关键引理:如果一个整数的*方是偶数,那么这个整数本身也是偶数。

    • (这个引理本身也可以用矛盾法证明:假设 n 是奇数,那么 n = 2k+1,则 n² = 4k² + 4k + 1 = 2(2k²+2k) + 1,结果是奇数,与 是偶数矛盾。所以 n 必须是偶数。)
    • 因此,n 是偶数,我们可以将其写为 n = 2kk 是某个整数)。
  4. 继续推导

    • n = 2k 代入等式 2 * d² = n²,得到:2 * d² = (2k)² = 4k²
    • 两边同时除以 2,得到:d² = 2k²
    • 现在,右边 2k² 能被 2 整除,所以左边 也能被 2 整除,即 是偶数。
    • 再次应用上面的关键引理,可知 d 也是偶数。
  5. 得出矛盾

    • 我们推导出 nd 都是偶数。这意味着它们都含有因子 2。
    • 但这与我们最初的假设——“nd 是互质的(没有共同的素因子)”——直接矛盾
  6. 完成证明

    • 由于我们的假设(√2 是有理数)导致了一个逻辑矛盾(nd 既互质又都有公因子2),因此这个假设必然是错误的
    • 所以,√2 不是有理数,即 √2 是无理数

总结

本节课中我们一起学*了矛盾证明法。我们首先通过一个计算立方根不等式的简单例子,直观感受了这种方法如何工作。然后,我们深入探讨了其核心逻辑:如果一个假设导致矛盾,则该假设不成立。最后,我们运用这一强大工具,完整地证明了 √2 是无理数 这一经典结论。矛盾证明法是逻辑推理的基石之一,在后续的数学和计算机科学学*中将会反复用到。

计算机科学的数学基础:P5:L1.2.3 - 分情况证明法 📚

在本节课中,我们将要学*一种基础的证明方法——分情况证明法。这种方法通过将一个复杂问题分解为几个更简单、易于证明的子情况,并且这些子情况共同覆盖了所有可能性,从而完成证明。


核心概念与示例

分情况证明法是一种将复杂问题拆解为多个简单子问题的策略。每个子问题都更容易处理,而所有子情况合起来则覆盖了原问题的全部可能性。

让我们来看一个来自计算机科学的明确而简单的例子。这是一个Java逻辑表达式:

if (x > 0 || (x <= 0 && y > 100)) {
    // 执行某些代码
}

如何解读这个表达式呢?在Java中,双竖线 || 表示逻辑“或”,双与符号 && 表示逻辑“与”。这是一个条件测试,如果测试结果为真,则执行后续的代码块。

这个测试可以解读为:如果 x 大于 0或者 x 小于等于 0 并且 y 大于 100,那么就执行代码块中的内容。我们假设变量 xy 是浮点数或整数类型。

现在,我断言这段代码可以被优化。如果将其重写为以下形式,程序的行为将完全一致:

if (x > 0 || y > 100) {
    // 执行相同的代码
}

这个断言是:用这个更短的表达式替换上面那个更长的表达式后,两个程序的行为方式将完全相同,因此后者更高效且更易于理解。


如何论证等价性

那么,如何论证这两段代码的行为完全相同呢?我们需要证明,在任何输入下,两个条件表达式的求值结果都一致。

我们可以通过考虑两种可能的情况来进行论证。

情况一:x > 0

首先,考虑 x 确实为正数,即 x > 0 的情况。

  • 在原始表达式中,x > 0 这部分为真。由于这是“或”运算的第一个操作数,整个表达式立即为真,因此会执行后续代码。
  • 在简化后的表达式中,x > 0 同样为真,整个表达式也为真,同样会执行后续代码。

因此,在 x > 0 的情况下,两个条件表达式都允许执行其后的代码。


情况二:x <= 0

接下来,考虑 x 小于或等于 0 的情况。

  • 在原始表达式中,x > 0 这部分为假。由于是“或”运算,当第一个操作数为假时,我们需要继续检查第二个操作数 (x <= 0 && y > 100)。已知 x <= 0 为真,所以这个子表达式的结果完全取决于 y > 100 是否为真。因此,整个原始表达式的结果等同于 y > 100 的结果。
  • 在简化后的表达式中,x > 0 为假,因此整个表达式的结果也完全取决于 y > 100 的结果。

所以,在 x <= 0 的情况下,两个条件表达式都简化为检查 y > 100,它们的行为也完全一致。


完成证明

综上所述,我们分析了所有可能的情况:

  1. x > 0 时,两个表达式都返回真。
  2. x <= 0 时,两个表达式都等同于 y > 100

由于 x 要么大于 0,要么小于等于 0,没有其他可能性,因此我们覆盖了所有情况。在所有情况下,两个表达式都产生相同的结果。这就证明了用更简单的表达式 (x > 0 || y > 100) 替换复杂的原始表达式 (x > 0 || (x <= 0 && y > 100)) 是安全的,它们完全等价。


方法总结与哲学探讨

上一节我们通过具体例子演示了分情况证明法。总的来说,分情况证明法通过将复杂问题分解为更容易解决的子问题来工作。在我们刚才的例子中,如果不分情况,很难直接看出两个表达式的等价性。但通过精心选择 x > 0x <= 0 这两种情况,每个子问题的论证都变得简单明了。

然而,有一些哲学家出于微妙的理由对分情况推理感到担忧,他们被称为直觉主义者。让我用一个例子来说明他们的担忧。

有一个价值百万美元的克雷数学研究所悬赏问题,即著名的 P 是否等于 NP 问题。P 代表多项式时间,NP 代表非确定性多项式时间。如果两者相等,将具有重大意义,但普遍认为它们不相等,只是无人能证明。

现在,我声称这个问题的答案就在我的讲台上。我将展示给你看。

我可以通过以下论证“证明”答案存在:

  1. 情况一:如果 P = NP,那么答案就是“是”。
  2. 情况二:如果 P ≠ NP,那么答案就是“否”。

在这两种情况下,答案都存在于我的讲台上(要么是“是”,要么是“否”)。直觉主义者反对这种推理,因为他们认为,除非你能实际构造出那个答案(即明确写出“是”或“否”),否则你不能声称答案“存在”。分情况证明在这里只是抽象地指出了两种可能性,并没有具体给出哪一个是真的。这展示了在数学基础中形式化证明与构造性证明之间有趣的差异。


本节课总结

本节课中我们一起学*了分情况证明法。我们首先了解了其核心思想:通过穷尽所有可能的情况,并在每个情况下分别进行证明,从而完成整体论证。接着,我们通过一个Java代码优化的具体实例,一步步演示了如何应用这种方法来证明两个逻辑表达式的等价性。最后,我们简要探讨了围绕该方法的一些哲学思考,了解了直觉主义者对非构造性证明的立场。掌握分情况证明法,能帮助我们将复杂的逻辑问题化整为零,逐一击破。

计算机科学的数学基础:P6:L1.3.1 - 良序原理1

📚 概述

在本节中,我们将学*一个在数学中非常基础且重要的概念——良序原理。这个原理看似显而易见,但它是许多数学证明和计算机科学论证的基石。我们将了解它的定义,探讨其适用范围,并通过一个经典例子来展示它的应用。


🔍 良序原理的定义

良序原理的陈述如下:每一个非空的非负整数集合都有一个最小元素

这个原理可能听起来很熟悉,甚至显而易见。我们可以这样理解:给定一个非空的整数集合,你可以从0开始检查它是否在集合中。如果0是集合的元素,那么它就是最小元素。如果不是,就检查1,然后是2,依此类推。由于集合非空,你最终一定会“碰到”那个最小的元素。这可以看作是一个非正式的证明。


⚠️ 原理的适用范围与限制

上一节我们介绍了良序原理的基本定义,本节中我们来看看它的适用范围和一些需要注意的细节。

良序原理只适用于非负整数。如果我们改变讨论的对象,结论可能不再成立。

以下是两个关键的限制情况:

  • 情况一:非负有理数。并非所有非负有理数集合都有最小元素。例如,考虑所有大于0的有理数集合,这个集合没有最小元素,因为无论你找到多小的正有理数,总能找到一个更小的。
  • 情况二:所有整数。所有整数的集合(包括负整数)没有最小元素,因为不存在“最小的”整数(例如,-1不是最小,-2比-1更小,以此类推)。

我们在日常生活中经常不自觉地使用这个原理。例如,当我们询问“麻省理工学院毕业生的最小年龄”或“任何动物拥有的最小神经元数量”时,我们默认存在这样一个最小的数字,这正是因为年龄和神经元数量都是非负整数。


🧮 符号约定与回顾

在后续的讨论中,除非特别说明,“数”将特指非负整数。数学中有一个标准符号来表示非负整数集合,即 (有时被称为自然数,但为了避免“0是否自然”的争议,我们统一称之为非负整数)。


💡 原理的早期应用:证明√2是无理数

实际上,我们已经在不知不觉中应用过良序原理了。回想一下证明√2是无理数的过程。

那个证明始于一个假设:假设√2是有理数,即它可以表示为两个整数的商 m/n。论证的关键一步是:任何分数都可以表示为最简形式(即分子和分母没有大于1的公因数)。更准确地说,如果存在一个分数等于√2,那么就存在一个没有公因数的“最简分数” m/n 使得 √2 = m/n

现在,我们可以用良序原理来清晰地论证为什么任何分数都能化为最简形式。具体论证如下:

  1. 考虑所有满足 √2 = m/n 的分数 m/n
  2. 根据良序原理,在所有可能的分子 m 中,存在一个最小的分子 m,使得 √2 可以表示为 m/n(其中 n 是某个对应的分母)。
  3. 我们声称,以这个最小分子 m 构成的分数 m/n 必然已经是最简形式。
  4. 反证法:假设 mn 有一个大于1的公因数 c。那么,我们可以将分数简化为 (m/c) / (n/c)。此时,分子 m/c 是一个比 m 更小的整数,并且它仍然满足 √2 = (m/c) / (n/c)
  5. 但这与我们最初选择的“最小分子 m”相矛盾。
  6. 这个矛盾表明,我们的假设(mn 有公因数)是错误的。因此,mn 没有公因数,分数 m/n 已经是最简形式。

注意:虽然我们是在证明√2是无理数的背景下引入这个论证的,但上述推理过程实际上证明了任何有理数(任何分数)都可以表示为最简形式


📝 总结

本节课中,我们一起学*了良序原理。我们明确了它的定义:每个非空的非负整数集合都有一个最小元素。我们探讨了它的局限性,了解到它不适用于有理数集或全体整数集。最后,我们回顾了在证明√2是无理数的过程中,如何巧妙地运用良序原理来论证分数总可以化为最简形式。理解这个原理将为后续学*更多数学证明方法打下坚实的基础。

计算机科学的数学基础:P7:L1.3.3 - 良序原理应用示例 🧮

在本节课中,我们将学*如何应用良序原理来证明两个重要的数学命题。良序原理指出:任何非空的自然数集合都有一个最小元素。我们将通过两个例子来展示这一原理的强大之处:第一个是证明每个大于1的整数都是质数的乘积,第二个是分析使用3分和5分邮票可以组成哪些邮资。


示例一:整数分解为质数乘积

上一节我们介绍了良序原理的基本概念,本节中我们来看看如何用它来证明一个关于整数分解的基本定理。

定理:每个大于1的整数都是质数的乘积。

证明:我们将使用反证法来证明这个定理。

  1. 假设存在反例:假设存在一些大于1的整数,它们不能表示为质数的乘积。也就是说,“非质数乘积”的集合是非空的。
  2. 应用良序原理:根据良序原理,这个非空的“非质数乘积”集合中必然存在一个最小的元素。我们记这个最小的反例为 M
  3. 分析M的性质:根据定义,M 大于1且不是质数的乘积。注意,如果 M 本身是质数,那么它被视为一个质数(自身)的乘积。因此,M 不可能是质数。
  4. 推导矛盾
    • 由于 M 不是质数,那么它可以表示为两个大于1且小于 M 的整数的乘积,即 M = J × K,其中 J, K > 1J, K < M
    • 因为 M 是“非质数乘积”集合中的最小元素,而 JK 都小于 M,所以 JK 必然可以表示为质数的乘积。假设:
      • J = P₁ × P₂ × ... × Pₐ
      • K = Q₁ × Q₂ × ... × Qᵦ
    • 那么,M = J × K = (P₁ × P₂ × ... × Pₐ) × (Q₁ × Q₂ × ... × Qᵦ)
    • 这个等式表明 M 本身也是质数的乘积,这与我们最初假设 M 是“非质数乘积”相矛盾。

由于假设存在反例导致了矛盾,因此原假设不成立。结论是:不存在不能表示为质数乘积的大于1的整数,即每个大于1的整数都是质数的乘积。


示例二:邮票组合问题

在理解了第一个例子后,我们来看一个稍微复杂但更有趣的应用,它涉及组合问题。

问题:假设我们拥有无限多的3分邮票和5分邮票。我们想要证明:任何不少于8分的邮资都可以用这两种邮票组合出来

为了使证明更简洁,我们引入一个定义:如果一个数 n 满足“n + 8 分邮资可以用3分和5分邮票组成”,则称 n 是“可邮寄的”。

目标:证明所有自然数 n 都是“可邮寄的”。换句话说,从8分开始的所有邮资都能被组成。

证明:我们再次使用反证法和良序原理。

  1. 假设存在反例:假设存在一些“不可邮寄”的数。那么,“不可邮寄数”的集合是非空的。
  2. 应用良序原理:根据良序原理,这个非空集合中存在一个最小的“不可邮寄数”。我们记这个最小的反例为 M
  3. 分析M的性质:我们知道 M 是“不可邮寄的”,并且所有比 M 小的数都是“可邮寄的”。
    • 首先,M 不能是0、1或2。
      • 0是可邮寄的,因为 0+8=8 分可以用 (1个3分 + 1个5分) 组成。
      • 1是可邮寄的,因为 1+8=9 分可以用 (3个3分) 组成。
      • 2是可邮寄的,因为 2+8=10 分可以用 (2个5分) 组成。
    • 因此,M ≥ 3
  4. 推导矛盾
    • 考虑 M - 3。因为 M ≥ 3,所以 M - 3 ≥ 0,并且 M - 3 < M
    • 由于 M 是最小的“不可邮寄数”,而 M - 3M 小,所以 M - 3 必然是“可邮寄的”。
    • “M - 3 可邮寄”意味着我们可以用3分和5分邮票组成 (M - 3) + 8 分的邮资。
    • 如果我们在这个 (M - 3) + 8 分的邮资组合中再额外加上一张3分邮票,那么我们就得到了 M + 8 分的邮资。
    • 但这恰恰证明了 M 是“可邮寄的”,与我们最初假设 M “不可邮寄”相矛盾。

假设存在最小的“不可邮寄数” M 导致了矛盾。因此,这样的 M 不存在。结论是:所有自然数 n 都是“可邮寄的”,即从8分开始的所有邮资都能用3分和5分邮票组合出来。


总结 📝

本节课中我们一起学*了良序原理的两个经典应用。

  • 首先,我们证明了每个大于1的整数都可以分解为质数的乘积,这是算术基本定理的核心思想之一。
  • 其次,我们解决了一个组合问题,证明了使用3分和5分邮票可以组成任何不少于8分的邮资

这两个例子展示了良序原理作为证明工具的通用模式:假设命题不成立 → 找出最小的反例 → 利用“最小性”推导出矛盾 → 从而证明命题成立。掌握这种方法对理解计算机科学中的许多算法正确性证明至关重要。

计算机科学的数学基础:1.3.5:良序原理应用3 🧮

在本节课中,我们将学*如何应用良序原理来证明一个关于几何级数求和的著名公式。我们将通过一个具体的例子,展示良序原理在证明数学恒等式中的强大作用。


概述

本节课我们将要学*良序原理的最后一个应用实例。我们将证明一个关于几何级数求和的公式。这个公式对于所有非负整数 n 和所有不等于1的实数 r 都成立。我们将看到,即使证明过程需要一些技巧,良序原理也能为我们提供一个清晰、严谨的证明框架。


几何级数求和公式

我们关注的定理是下面这个关于几何级数求和的著名公式:

对于几何级数(或称几何和),其形式为从 r⁰rⁿ 的幂次之和。具体来说,左边的数字序列是:1(即 r⁰),,……,直到 rⁿ。将这些数字全部相加,结果可以用一个简洁的封闭公式表示,而不需要使用省略号。

该公式准确地给出了和的值,如下所示:

公式:

∑_{i=0}^{n} rⁱ = (r^{n+1} - 1) / (r - 1)

这个恒等式对所有非负整数 n 成立,并且对所有不等于 1 的实数 r 成立(因为分母不能为零)。


使用良序原理进行证明

我们如何证明这个公式呢?我们将使用良序原理。

首先,我们假设这个恒等式对某些非负整数 n 成立。接下来,我们应用良序原理。

  1. 定义反例集合:C 是使该等式不成立的所有非负整数 n 的集合。即 C = { n | P(n) 为假 },其中 P(n) 表示等式在 n 时成立。
  2. 寻找最小反例: 根据良序原理,如果 C 非空(即存在反例),那么 C 中必然存在一个最小的元素。我们设这个最小的反例为 m。因此,m 是使等式不成立的最小非负整数。

现在,我们对这个最小的反例 m 进行分析。

我们知道,当 n = 0 时,等式左边是 r⁰ = 1。等式右边是 (r¹ - 1)/(r - 1) = 1。因此,当 n = 0 时,等式成立。这意味着,等式不成立的最小 m 必须是正数(即 m > 0)。

由于 m最小的反例,那么对于所有小于 m 的非负整数(即从 0m-1),等式都成立。这是一个关键点。

因此,我们可以假设对于 n = m-1,等式成立:

∑_{i=0}^{m-1} rⁱ = (r^{(m-1)+1} - 1) / (r - 1) = (r^{m} - 1) / (r - 1)

推导矛盾

我们感兴趣的是 n = m 时的和,即 ∑_{i=0}^{m} rⁱ。我们可以利用已知的 m-1 的情况来构造它。

m-1 的和出发,两边同时加上 rᵐ

∑_{i=0}^{m} rⁱ = [∑_{i=0}^{m-1} rⁱ] + rᵐ

将我们假设成立的等式代入:

∑_{i=0}^{m} rⁱ = [(r^{m} - 1) / (r - 1)] + rᵐ

现在,我们化简右边的表达式。将 rᵐ 写成分母为 (r-1) 的形式:

rᵐ = rᵐ * (r - 1) / (r - 1) = (r^{m+1} - rᵐ) / (r - 1)

将其与前面的分式相加:

∑_{i=0}^{m} rⁱ = [(r^{m} - 1) + (r^{m+1} - rᵐ)] / (r - 1)

合并分子中的项:

∑_{i=0}^{m} rⁱ = (r^{m+1} - 1) / (r - 1)

看!我们恰好得到了当 n = m 时,原公式右边的形式。这意味着,根据我们“等式在 m-1 时成立”的假设,我们推导出等式在 n = m也必然成立


完成证明

但这与我们最初的设定矛盾!我们最初设定 m 是使等式不成立的最小反例。然而,上面的推导却表明,如果等式在 m-1 时成立,那么它在 m 时也成立。因此,m 不可能是一个反例。

这个矛盾源于我们最初的假设——“存在至少一个 n 使等式不成立”。既然这个假设导致了矛盾,那么它必然是假的。

因此,我们得出结论:不存在使等式不成立的非负整数 n。也就是说,该几何级数求和公式对所有非负整数 n 都成立。


良序原理证明模板总结

上一节我们通过一个具体例子完成了证明,本节我们来总结一下使用良序原理进行证明的一般组织框架。这可以作为一个通用的证明模板。

目标: 证明某个性质 P(n) 对所有非负整数 n 都成立。

以下是证明步骤:

  1. 假设存在反例: 假设结论不成立,即存在至少一个非负整数使得 P(n) 为假。定义反例集合 C = { n | P(n) 为假 }
  2. 寻找最小反例: 根据良序原理,如果 C 非空,则其中存在一个最小的元素。记这个最小的反例为 m
  3. 推理得出矛盾: 这是证明的核心,没有固定套路。通常通过以下两种方式之一利用“m 是最小反例”这一事实进行推理:
    • 方式一: 证明存在另一个反例 c,且 c < m。这与“mC 中最小元素”矛盾。
    • 方式二: 证明 P(m) 实际上成立(就像我们在几何级数例子中所做的)。这与“m 是反例(即 P(m) 为假)”的设定直接矛盾。
  4. 得出结论: 由于假设存在反例会导出矛盾,因此原假设错误。故性质 P(n) 对所有非负整数 n 都成立。

本节课总结

在本节课中,我们一起学*了良序原理的第三个重要应用。我们使用它严谨地证明了几何级数的求和公式。通过假设存在一个最小的反例 m,并利用 m-1 时公式成立的归纳思想,我们推导出 m 时公式也必须成立,从而否定了最小反例的存在,完成了证明。最后,我们总结了使用良序原理进行证明的通用模板,它为我们证明关于非负整数的命题提供了一个强大而清晰的方法。

计算机科学的数学基础:P9:L1.4.1 - 命题与逻辑运算符 🧠

在本节课中,我们将要学*命题逻辑的基础知识,包括什么是命题,以及如何使用逻辑运算符(如“与”、“或”、“非”等)来构建更复杂的复合命题。理解这些概念是进行严谨数学推理和编程的基础。

什么是命题?

对一个数学家来说,尤其是在这门课上,我们将使用“命题”这个词,指代一个可以明确判断为真或为假的事物。

例如,“有五种正多面体”是一个命题,它恰好是真的。在某些方面,我们甚至可以证明这一点。它暗示着,假设你想让一百颗卫星以统一的方式绕着地球运行,你做不到,因为没有一百个顶点的正多面体,最大的正多面体只有二十个顶点。

如果我将命题换成“有六个正多面体”,那么这个断言就是假的。所以,这是一个定义良好的命题的简单例子,其中一个是真的,另一个是假的。命题不一定是真的,总存在一些非真的例子。

“醒一醒”不是一个命题,因为这是一个祈使句,没有真假之分。“我在哪里”是一个问题,也没有真假之分。“是三便士”不是一个命题,因为它在任何特定的时刻可能是真的或假的,但其真假取决于时间,这是一个复杂的问题,我们不想深入探讨。一个命题是一个固定的断言,它要么永远为真,要么永远为假。

为什么需要形式逻辑?

数学家提出命题抽象以及对其运算的原因之一是,普通语言往往模棱两可,这会给数学推理带来问题,就像在程序设计中一样。

英语中连接命题的最模棱两可的短语之一是“或”。让我们看一个例子:“希腊人意味着拿着剑或标枪”。如果我把这个转录成精确的数学符号,我可以说:G 代表“是希腊人”意味着 S 代表“拿着剑”或 J 代表“拿着标枪”。所以,这是一个断言:如果你是希腊人,那么你拿着剑或标枪。

问题在于“或”意味着什么?事实证明,对于标枪和剑来说,即使一个希腊人同时带着剑和标枪,这个断言也为真。这是一个“包容性的或”。一个希腊士兵确实可能同时带着剑和标枪,因为标枪是很好的长距离武器,而剑在*处用于自卫很好,你当然想两者兼得。

逻辑运算符及其符号

这些逻辑连接词有许多标准符号,用于从简单的命题构建更大的命题。

其中之一是 符号,这个连接符号是逻辑学家经常用来代替“或”的。箭头 表示“蕴含”,有时双杠箭头 也意味着“蕴含”。但我们不打算深入讨论这些,我们主要使用词语来描述。

让我们看另一个例子:“希腊人佩带青铜或铜剑”。语法上,这与前一个短语的结构相同,但我们要用不同的方式翻译它。原因在于,这里指的是一个希腊士兵不会同时携带一把青铜剑和一把铜剑。因为青铜剑比铜剑好很多,它们要硬得多。所以这次我们的意思是,希腊人只携带青铜或铜制武器中的一种。如果你没有青铜的,你才会带铜的。

所以现在我们把它翻译成:希腊人意味着 B(青铜)或 C(铜),但这次我们用“异或”(XOR)。XOR意味着其中一个是正确的,但不是两者都有。XOR有一个加号表示法 ,因为我们将看到,它的行为有点像模2加法:1 ⊕ 1 = 0

精确定义 OR 和 XOR

让我们更精确地定义 OR 和 XOR 以及它们是如何工作的。

断言是:如果 PQ 是代表真或假命题的占位符,那么复合命题 P OR Q 为真,当且仅当 P 为真,或 Q 为真,或者两者都为真。

我可以用一个所谓的“真值表”来表达这个断言。在表中,我列举了 PQ 所有可能的真值组合,并告诉你 P OR Q 对应的真值。

P Q P OR Q
T T T
T F T
F T T
F F F

值得注意的是,P OR Q 为假的唯一方法是 PQ 都为假。

对于 XOR,P XOR Q 为真,当且仅当 PQ 中正好有一个为真。

P Q P XOR Q
T T F
T F T
F T T
F F F

这个真值表只是定义 XOR 如何作用于真值的精确方法。

其他基本运算符:AND 和 NOT

还有另一个连接词 AND,它的工作方式更直接。P AND Q 的值为真,当且仅当 PQ 都为真。

P Q P AND Q
T T T
T F F
F T F
F F F

突出的一点是,P AND Q 为真仅当 PQ 都为真。

逻辑运算中还有否定运算 NOT。NOT P 只是翻转了 P 的真值。如果 P 为真,那么 NOT P 是假的;如果 P 为假,那么 NOT P 是真的。

P NOT P
T F
F T

在编程中的应用

使用逻辑运算来构建更复杂的复合命题的一个主要应用领域是在编程中。

这里有一个来自 Java 的典型短语。Java 使用双竖线 || 来表示“包容性或”,使用双与号 && 来表示“与”。

if (x > 0 || (x <= 0 && y > 100)) {
    // 执行一些代码
}

这是一段合法的 Java 代码。它正在测试并求值此表达式:如果 x 大于零,或者(x 小于等于零且 y 大于一百),那么如果那个测试为真,则执行大括号内的代码;如果是假的,则跳过所有代码继续执行。

在大多数编程语言中,我们以非常标准的方式使用类似这样的布尔表达式或逻辑表达式。

在数字逻辑中的应用

这些操作出现的另一个地方是在数字逻辑,即数字电路设计中。数字电路设计者有自己的符号。

一个常用的缩写是:NOT x 可以通过在 x 上写一个横杠 来表示。更一般地,NOT 可以通过在复杂的表达式上写一个横杠来缩写,这可以节省空间。我们会使用这个符号。

在数字逻辑中,电路处理的是电信号,其唯一区别是高电压还是低电压。高电压用 1 表示,低电压用 0 表示。数字逻辑的行为方式是:1 对应于真(True),0 对应于假(False)。

那么 AND 运算就是简单的乘法,因为对于 10 的普通乘法,只有当两者都为 1 时,结果才为 1。这正是当 1 表示为真、0 表示为假时 AND 运算的行为方式。

1 AND 1 = 1 * 1 = 1
1 AND 0 = 1 * 0 = 0
0 AND 1 = 0 * 1 = 0
0 AND 0 = 0 * 0 = 0

不幸的是,数字设计师在他们使用 + 表示 OR 时,并不意味着普通加法(1+1=2),而是意味着 1 OR 1 = 1。这是需要注意的一部分,也是我们不常使用这个 + 符号表示 OR 的部分原因。

总结

本节课中我们一起学*了命题逻辑的基础。我们首先定义了命题是能判断真假的陈述。然后,我们探讨了普通语言的模糊性如何促使我们使用形式化的逻辑运算符,包括 OR(∨)XOR(⊕)AND(∧)NOT(¬)。我们通过真值表精确地定义了这些运算符的行为。最后,我们看到了这些概念在编程(如Java中的条件判断)和数字电路设计中的实际应用。理解这些基本构件是进行更复杂数学推理和计算机科学学*的关键一步。

计算机科学的数学基础:1.4.3:数字逻辑 🧮

在本节课中,我们将学*命题运算符在数字电路设计中的基础作用。我们将通过设计一个简单的二进制加法电路来具体说明这一点。

二进制表示与加法回顾

二进制的工作原理与十进制类似,区别在于它使用2的幂次方,而非10的幂次方。例如,数字39的二进制表示是 100111。理解方式是:从右向左,依次是1位、2位、4位、8位、16位、32位。因此,1+2+4=7,加上32位上的1,32+7=39

同样,数字28的二进制表示是 011100。你可以通过计算1*4 + 1*8 + 1*16来验证。

二进制加法与十进制加法类似,但数字只有0和1。当1+1时,会产生进位。让我们计算100111(39)加上011100(28):

  • 第一列:1+0=1
  • 第二列:1+0=1
  • 第三列:1+1=0,进位1
  • 第四列:1+1+进位1=1,进位1
  • 第五列:0+1+进位1=0,进位1
  • 第六列:1+0+进位1=0,进位1
  • 第七列:进位1
    最终结果是 1000011,即1+2+64=67

设计二进制加法电路

现在,我们尝试使用数字逻辑(信号0和1)来设计一个执行加法运算的电路。我们的目标是设计一个6位二进制加法电路。

我们将有两个输入:第一个6位二进制数 A5, A4, ..., A0 和第二个6位二进制数 B5, B4, ..., B0。这些0或1信号将通过导线传入一些包含数字运算符的“盒子”中。

我们希望输出的是这两个数二进制和的可能为7位的表示:S0, S1, ..., S5 以及可能的高位进位 C5S0A0B0相加后的低位(可能考虑进位),依此类推。如果两个6位数相加产生7位数,C5就会是1。

实现方式很明确:处理AB输入以产生低位数字的“盒子”可能会产生一个进位,这个进位必须传递到下一列(如果存在)。因此,我们需要一根导线将这个盒子产生的0或1进位信号传递给下一个盒子。

这种结构被称为行波进位加法器。它精确地模仿了我们逐列相加两个数字、可能将进位传播到下一列的方式。

半加器与全加器

这些“盒子”需要具体设计。第一个盒子(处理最低位)只有两个输入(A0B0),而其他盒子都有三个输入(Ai, Bi和来自低位的进位Ci-1)。

因此,我们将三输入盒子称为全加器,两输入盒子称为半加器

  • 半加器的规格是:输入为AB,输出是A+B的二进制表示(一个两位数,因为最大和为2)。我们称低位输出为D,进位输出为C
  • 全加器的规格是:输入为AB和进位输入C_in,输出是A+B+C_in的二进制表示(一个两位数,因为最大和为3)。

上一节我们介绍了电路的基本结构,本节我们来看看构成这些结构的基本单元——半加器和全加器是如何实现的。

半加器设计

半加器相对简单。它的输入是AB,需要产生A+B的二进制和。低位DAB的模2和(即异或运算),进位C仅在AB都为1时发生(即与运算)。

以下是半加器的电路逻辑描述:

  • D被定义为AB的异或:D ::= A XOR B
  • C被定义为AB的与:C ::= A AND B

全加器设计

全加器稍微复杂一些。我们可以用两个半加器和一个或门来构建它。

首先,我们引入一个中间变量s,它是输入AB的异或:s ::= A XOR B

全加器的输出可以如下描述:

  1. 和输出D是进位输入C_in与中间变量s的异或:D ::= C_in XOR s
  2. 进位输出C_out有两个来源:
    • 第一个半加器产生的进位:A AND B
    • 第二个半加器(处理sC_in)可能产生的进位:C_in AND s
      因此,总进位输出是这两者的或:C_out ::= (A AND B) OR (C_in AND s)

电路行为的公式化描述

现在我们已经有了描述半加器和全加器行为的公式,可以回到我们的行波进位加法器,用公式来描述所有输出(C_iD_i)的行为。

对于第一个半加器(处理最低位i=0):

  • D0 ::= A0 XOR B0
  • C0 ::= A0 AND B0

对于后续的每一个全加器(i从1到5):

  • 首先定义中间变量:s_i ::= A_i XOR B_i
  • 然后,和输出为:D_i ::= C_{i-1} XOR s_i
  • 最后,进位输出为:C_i ::= (A_i AND B_i) OR (C_{i-1} AND s_i)

关键在于,我们已经将电路的具体连线图翻译成了这样一组逻辑方程。这些方程更能体现电路的逻辑行为,因为它不依赖于具体的物理布局,只依赖于这些逻辑关系。

总结

本节课中,我们一起学*了数字逻辑的基础。我们从二进制表示和加法开始,然后逐步设计了一个6位行波进位加法器。我们定义了构成该电路的基本单元:半加器全加器,并给出了它们的逻辑实现(使用异或、与、或门)。最后,我们将整个加法电路的行为用一组清晰的逻辑公式进行了描述,这比具体的电路图更能体现其计算本质。这展示了命题逻辑运算符在硬件设计中的直接应用。

计算机科学的数学基础:1.4.4:真值表 📊

在本节课中,我们将学*如何使用真值表来定义和理解命题逻辑中公式的行为。真值表是一种系统化的方法,可以帮助我们判断公式是否等价,或者一个公式是否总是成立(即有效)。


环境与赋值

上一节我们介绍了命题连接词,本节中我们来看看如何评估一个复合命题公式的真值。为了确定整个公式的真假,我们需要知道其各个组成部分(即原子命题变量)的真假值。

在计算机科学中,为变量分配值的过程称为环境。逻辑学家则称之为真值赋值。环境是一个函数,它告诉我们每个变量是还是

让我们看一个例子。假设有三个变量 PQR。我们有一个环境 V,其中:

  • V(P) = True
  • V(Q) = True
  • V(R) = False

现在,我们想评估复合公式 (P AND Q) XOR (NOT Q) 在这个环境下的值。

以下是评估步骤:

  1. 将环境中的值赋给变量:P=True, Q=True, R=False。
  2. 从最内层的子公式开始计算:
    • P AND Q:由于 P 和 Q 都为真,所以结果为 True
    • NOT Q:Q 为真,所以结果为 False
  3. 计算外层连接词:
    • (True) XOR (False):XOR 在两边值不同时为真,所以结果为 True

这个过程可以递归地进行,从内到外或从上到下,最终得到整个公式的真值。


公式的等价性

两个命题公式是等价的,当且仅当它们在所有可能的环境下都具有相同的真值。真值表是验证等价性的完美工具。

一个重要的等价关系是德摩根定律。它指出:

  • NOT (P OR Q) 等价于 (NOT P) AND (NOT Q)

我们可以通过真值表来证明:

以下是 NOT (P OR Q) 的真值表:

P Q P OR Q NOT (P OR Q)
T T T F
T F T F
F T T F
F F F T

以下是 (NOT P) AND (NOT Q) 的真值表:

P Q NOT P NOT Q (NOT P) AND (NOT Q)
T T F F F
T F F T F
F T T F F
F F T T T

比较两表的最后一列,它们完全相同。因此,我们通过穷举所有可能环境(即真值表)证明了这两个公式是等价的。


“当且仅当”连接词

现在,我们引入一个新的重要连接词:当且仅当,记作 IFF

公式 P IFF Q 的真值定义为:当 PQ 的真值相同时为真,否则为假。

其真值表如下:

P Q P IFF Q
T T T
T F F
F T F
F F T

可以发现,P IFF Q 为真,恰好与 (NOT (P XOR Q)) 为真是同一回事。这个连接词在表达等价关系时非常有用。


可满足性与有效性

基于真值表,我们可以定义两个核心概念:

  1. 可满足性:一个公式是可满足的,当且仅当存在至少一个环境使其为真。

    • 例如:P 是可满足的(令 P=True 即可)。
    • 例如:P AND NOT P不可满足的(无论P取何值,该公式恒为假)。
  2. 有效性(永真式):一个公式是有效的(或称永真式),当且仅当它在所有可能的环境下都为真。

    • 例如:P OR NOT P 是有效的(P要么真,要么假,总有一成立)。
    • 例如:根据德摩根定律,(NOT (P OR Q)) IFF ((NOT P) AND (NOT Q)) 是一个永真式,因为它表达了一个等价关系。

可满足性与有效性通过以下方式紧密关联:

  • 公式 G 是有效的,当且仅当 NOT G不可满足的
  • 公式 G 是可满足的,当且仅当 NOT G无效的(不是永真式)。


计算的挑战:P vs NP 问题

使用真值表判断可满足性或有效性在理论上是直接且完备的。然而,这种方法存在一个巨大的实践问题:状态空间爆炸

对于一个有 n 个变量的公式,其真值表有 2^n 行。这意味着:

  • 2个变量:4行
  • 3个变量:8行
  • 4个变量:16行
  • ...
  • 100个变量:约 1.3 x 10^30 行——这是一个天文数字,无法实际计算。

因此,一个核心的理论计算机科学问题是:是否存在一种比穷举所有真值赋值(指数时间)更高效(例如多项式时间)的方法,来判断一个命题公式是否可满足?

这就是著名的 P vs NP 问题。SAT(布尔可满足性问题)是NP完全问题的典型代表。目前,没有人知道是否存在解决SAT问题的高效算法。如果能找到,将意味着P=NP,这将是计算机科学领域的革命性发现;如果证明不存在,则确认了P≠NP。

由于有效性问题(检查 G 是否永真)可以转化为可满足性问题(检查 NOT G 是否不可满足),所以这两个问题的计算难度是相同的。


总结

本节课中我们一起学*了:

  1. 如何使用环境(赋值)来递归地评估命题公式的真值。
  2. 如何利用真值表这一系统化工具来证明两个公式的等价性,例如德摩根定律。
  3. 认识了“当且仅当”连接词及其真值表。
  4. 理解了可满足性(存在为真的情况)和有效性(永真式)这两个关键概念及其相互关系。
  5. 初步了解了SAT问题的挑战性及其与P vs NP这一计算机科学核心未解问题的关联。真值表方法虽然直观,但在变量较多时因指数级增长而不可行,这引出了对更高效算法的探索。

计算机科学的数学基础:P12:L1.5.1-谓词逻辑1 🧠

在本节课中,我们将要学*谓词逻辑的基本概念,特别是两个核心量词:全称量词存在量词。我们将通过具体的例子来理解什么是谓词,以及量词如何改变命题的含义。

什么是谓词?

上一节我们介绍了命题逻辑,本节中我们来看看谓词。谓词本质上是一个包含变量的命题。为了判断一个谓词的真假,我们需要知道其中变量的具体值。

例如,我们可以定义一个依赖于变量 xy 的谓词 P(x, y),其含义为 x + 2 = y

  • 如果 x = 1, y = 3,则 P(1, 3) 为真,因为 1 + 2 = 3
  • 如果 x = 1, y = 4,则 P(1, 4) 为假,因为 1 + 2 ≠ 4

量词:全称与存在

理解了谓词后,现在我们来引入控制变量的量词。量词主要有两种:

  • 全称量词:符号为 ,读作“对于所有”。
  • 存在量词:符号为 ,读作“存在”。

为了理解它们的作用,我们来看一个例子。假设变量 s 的取值范围是某课程 6.042 的所有工作人员(大约30人)。我们定义谓词 P(s) 表示“工作人员 s6.042 充满热情”。

以下是量词的应用方式:

  • 全称量词:命题 ∀s P(s) 表示“对于所有工作人员 sP(s) 都为真”。这相当于说:德鲁充满热情,彼得充满热情,克沙夫充满热情……所有30名工作人员都充满热情。
  • 存在量词:定义另一个谓词 B(t) 表示“工作人员 t 之前上过 6.042”。命题 ∃t B(t) 表示“存在一个工作人员 t,使得 B(t) 为真”。这意味着至少有一名工作人员(德鲁、彼得、克沙夫或米凯拉等中的某一位)之前上过这门课。

量词应用练*

让我们通过一些数学例子来巩固对量词的理解。假设变量 xy 的取值范围是非负整数(即 0, 1, 2, 3, …)。

存在量词练*

考虑谓词 Q(y)∃x (x < y),其含义是“存在一个 x,使得 x 小于 y”。

  • Q(3) 为真,因为可以取 x = 1(或0, 2),满足 1 < 3
  • Q(1) 为真,因为可以取 x = 0,满足 0 < 1
  • Q(0) 为假,因为不存在一个非负整数 x 能满足 x < 0

全称量词练*

考虑谓词 R(y)∀x (x < y),其含义是“对于所有 x,都有 x 小于 y”。

  • R(1) 为假。反例:取 x = 55 < 1 不成立。
  • R(8) 为假。反例:取 x = 1212 < 8 不成立。
  • 事实上,对于任何有限的 yR(y) 都为假,因为总可以找到一个比 y 大的 x(例如 x = y + 1)。

量词的顺序至关重要

初学者容易混淆的一点是量词的顺序,不同的顺序会导致命题的含义发生根本改变。

让我们看一个直观的例子:假设 v 代表计算机病毒,d 代表防御软件。

  • 命题 A∀v ∃d (d defends against v)
    • 含义:对于每一种病毒,都存在一种能防御它的软件。
    • 解读:每种病毒都有对应的克星,但针对不同病毒可能需要不同的软件。这成本可能很高。
  • 命题 B∃d ∀v (d defends against v)
    • 含义:存在一种软件,能防御所有病毒。
    • 解读:存在一种“万能”防御软件,可以抵御所有攻击。这显然更理想、更经济。

可以看到,∀∃∃∀ 的含义截然不同。

论域对命题真值的影响

一个含有量词的命题是否为真,严重依赖于变量论域(即取值范围)的选择。

考虑命题 G∀x ∃y (y > x),其含义是“对于每一个 x,都存在一个 y 使得 y 大于 x”。

  • 如果论域是非负整数G 为真。因为给定任何非负整数 x,总可以取 y = x + 1
  • 如果论域是负整数G 为假。例如当 x = -1 时,不存在比 -1 更大的负整数。
  • 如果论域是负实数G 又为真。因为给定任何负实数 r,取 y = r / 2(它比 r 更接*0,所以更大)。

颠倒量词的顺序

现在让我们颠倒量词,考虑命题 H∃y ∀x (x ≤ y),其含义是“存在一个 y,使得对于所有 x,都有 x 小于或等于 y”。这实际上是在断言论域中存在一个最大值 y

  • 如果论域是非负整数H 为假。因为对于任何整数 yy+1 都比它大。
  • 如果论域是负整数H 为真。最大值 y 就是 -1
  • 如果论域是负实数H 为假。因为对于任何负实数 yy / 2 都比它大。

这个例子再次说明,量词顺序和论域共同决定了命题的真假。

总结

本节课中我们一起学*了谓词逻辑的核心内容:

  1. 谓词是包含变量的命题,其真值取决于变量的赋值。
  2. 两个基本量词
    • 全称量词 :表示“对于所有……”。
    • 存在量词 :表示“存在至少一个……”。
  3. 量词的顺序极其重要,∀x ∃y P(x,y)∃y ∀x P(x,y) 含义完全不同。
  4. 含有量词的命题的真值依赖于变量的论域。改变论域可能会翻转命题的真假。

理解谓词和量词是掌握更复杂数学表述和进行严谨逻辑推理的基础。

计算机科学的数学基础:P13:L1.5.2:谓词逻辑 2 🔍

在本节课中,我们将要学*谓词逻辑中的两个核心概念:有效性可满足性。我们将通过具体的公式和例子,理解如何判断一个谓词逻辑公式是否总是为真,以及如何构造反例来证明其不总是为真。


有效性概念回顾 📚

上一节我们介绍了命题逻辑的有效性。现在,我们来看看它在谓词逻辑中的扩展。

在命题逻辑中,一个公式是有效的,当且仅当对于其变量的所有可能的真值赋值,该公式的结果都为真。例如,公式 (p → q) ∨ (q → p) 是有效的,因为无论 pq 取真或假,整个公式始终为真。

在谓词逻辑中,情况更为复杂。一个谓词逻辑公式是有效的,当且仅当对于所有可能的话语领域(即变量取值的非空集合),以及对于公式中提到的所有谓词的所有可能解释,该公式都为真。换句话说,公式的真理性不依赖于特定的领域或谓词的具体含义。

以下是理解有效性的一个关键公式示例:

∀z (P(z) ∧ Q(z)) → (∀x P(x) ∧ ∀y Q(y))

这个公式是有效的。它陈述的是:如果领域中的每个元素 z 都同时满足性质 PQ,那么自然可以推出“所有 x 都满足 P”并且“所有 y 都满足 Q”。这是一个逻辑事实,不依赖于 PQ 的具体含义或领域的构成。


如何论证有效性? 🛠️

本节中,我们来看看如何非正式地论证一个谓词公式的有效性。我们以上述公式为例。

论证策略是假设蕴含式()的左边为真,然后推导出右边也为真。

  1. 假设∀z (P(z) ∧ Q(z)) 为真。这意味着对于领域中的任意元素 cP(c)Q(c) 都成立。
  2. 推导:由于 c 是领域中任意选取的元素,且 Q(c) 成立,我们可以得出结论:∀x Q(x) 成立。同理,由 P(c) 成立可推出 ∀y P(y) 成立。
  3. 结论:因此,(∀x P(x) ∧ ∀y Q(y)) 为真。由假设推导出结论,证明了整个蕴含式为真。

这个推导过程用到了一个基本的逻辑推理规则——全称概括

如果证明了对于某个未做特殊假设的常量 `c` 有 `P(c)` 成立,那么可以推出 `∀x P(x)` 成立。

在逻辑符号中,这条规则常写作:

P(c)
------
∀x P(x)

(适用条件:c 不出现在关于 P 的其他未证假设中)


如何证明无效性? ⚠️

理解了有效性后,我们来看看如何证明一个公式不是有效的,即它是可满足的但非永真。方法是构造一个反例模型

考虑以下公式:

(∀z (P(z) ∨ Q(z))) → (∀x P(x) ∨ ∀y Q(y))

我们需要证明这个公式是无效的。为此,我们需要找到一个具体的领域和对谓词 PQ 的解释,使得该蕴含式的前件(左边)为真,但后件(右边)为假

以下是构造反例的步骤:

  1. 选择领域:选择最简单的非空领域,例如只包含两个元素:{1, 2}
  2. 解释谓词
    • P(z) 表示 “z = 2”。
    • Q(z) 表示 “z = 1”。
  3. 验证前件:公式 ∀z (P(z) ∨ Q(z)) 意为“所有 z 要么等于2,要么等于1”。在领域 {1, 2} 中,这显然为真。
  4. 验证后件:公式 ∀x P(x) ∨ ∀y Q(y) 意为“所有 x 都等于2” 或者 “所有 y 都等于1”。
    • ∀x P(x) 是假的,因为 1 不等于 2
    • ∀y Q(y) 是假的,因为 2 不等于 1
    • 因此,整个析取式为假。
  5. 得出结论:在这个模型中,蕴含式前真后假,所以整个公式为假。这证明了该公式不是有效的

量词与德摩根定律 ⚖️

最后,我们来看一个在谓词逻辑中同样重要的有效公式,它是命题逻辑中德摩根定律的推广。

在命题逻辑中,德摩根定律为:

¬(p ∧ q) ≡ (¬p ∨ ¬q)
¬(p ∨ q) ≡ (¬p ∧ ¬q)

在谓词逻辑中,全称量词()和存在量词()之间也存在类似的关系。一个重要的有效公式是:

¬∀x P(x) ≡ ∃x ¬P(x)

这个公式可以理解为:“并非所有东西都有性质 P” 等价于 “存在某个东西没有性质 P”。这直观上很好理解,也是进行逻辑推理和公式变换时的一个有力工具。


总结 📝

本节课中我们一起学*了谓词逻辑的核心概念:

  1. 有效性:一个公式对所有可能的领域和谓词解释都为真。我们通过逻辑推导来论证有效性。
  2. 无效性:一个公式并非总是为真。我们通过构造具体的反例模型(指定领域和谓词含义)来证明其无效性。
  3. 关键规则:我们接触了全称概括规则,并看到了德摩根定律在量词上的表现形式。

理解有效性与可满足性是分析逻辑语句、进行严谨数学证明的基础。通过具体的例子和构造练*,我们可以更好地掌握这些抽象概念。

计算机科学的数学基础:P14:谓词逻辑 3

在本节课中,我们将要学*谓词逻辑的最后两个议题。首先,我们会探讨将全称量词和存在量词从英语翻译成逻辑时可能遇到的一些问题。英语本身具有模糊性,我们将通过两个有趣的例子来说明翻译并非总是机械的。其次,我们将简要介绍元数学领域中的两个重要定理,它们描述了谓词演算的性质与极限。这部分内容是选学的,但有助于你理解逻辑系统的能力与边界。

英语翻译中的歧义问题

上一节我们介绍了谓词逻辑的基本翻译。本节中我们来看看从英语翻译到逻辑表达式时可能遇到的陷阱。英语的表述有时并不直接对应逻辑量词的顺序,需要我们根据语境理解其真实含义。

以下是两个需要仔细处理的英语句子翻译示例。

  • “All that glitters is not gold.”

    • 字面翻译:∀x (G(x) → ¬Au(x))。这个翻译是错误的,因为它声称所有发光的东西都不是金子,这显然不符合事实(因为金子本身就会发光)。
    • 正确理解:诗人实际想表达的是“并非所有发光的东西都是金子”。因此,正确的逻辑翻译应为:¬∀x (G(x) → Au(x))。这个例子说明,不能仅凭字面顺序进行翻译,而需理解句子的深层含义。
  • “There is a season to every purpose under heaven.”

    • 字面翻译:∃s ∀p (SeasonFor(s, p))。这个翻译意味着存在一个季节(例如夏天)适用于所有目的,这显然不合理(夏天不适合铲雪)。
    • 正确理解:这句话的实际含义是“对于每一个目的,都存在一个适合的季节”。因此,量词的顺序需要调换,正确的逻辑翻译应为:∀p ∃s (SeasonFor(s, p))。这个例子再次表明,英语表述中的量词顺序可能与逻辑上应有的顺序相反。

关于谓词演算的元定理

在探讨了翻译的复杂性之后,我们现在转向一个更理论化的话题,看看关于谓词逻辑系统本身有哪些深刻的数学结论。这些定理属于“元数学”的范畴,即研究数学本身(特别是数学逻辑)的数学。

以下是两个基础且重要的元定理。

  • 哥德尔完备性定理

    • 这是一个“好消息”定理。它指出,仅使用少数几条公理和推理规则(例如假言推理和全称推广),理论上就足以证明所有在谓词逻辑中有效的陈述。这意味着,任何逻辑上为真的命题,都可以从这个简单的系统中推导出来。尽管在实际的自动定理证明中需要更复杂的系统,但该定理在理论上具有重要意义。
  • 丘奇-图灵不可判定性定理

    • 这是一个“坏消息”定理。它指出,不存在一个通用的算法(或计算机程序),能够判定任意一个给定的谓词逻辑公式是否有效(永真)。这与命题逻辑不同,命题逻辑公式可以通过真值表(至少在理论上)进行判定。谓词逻辑的“不可判定性”意味着,我们无法编写一个总能给出“是”或“否”答案的程序来解决所有谓词公式的有效性问题。

本节课中我们一起学*了谓词逻辑的最后两部分内容。我们首先通过两个例子,认识到将英语翻译成逻辑表达式时,必须超越字面意思,理解量词的真实逻辑顺序。随后,我们简要了解了关于谓词演算系统的两个元定理:哥德尔完备性定理揭示了系统在证明能力上的完整性,而丘奇-图灵不可判定性定理则指出了该系统在自动判定问题上的根本限制。

计算机科学的数学基础:P15:L1.6.1-集合定义 📚

在本节课中,我们将学*数学中最基础的数据类型——集合。我们将从定义开始,通过示例来理解集合的基本概念,包括成员关系、子集、集合的表示方法以及幂集。


集合的非正式定义

集合是数学对象的集合。其核心思想是将一组对象视为一个新的、单一的对象。这是一个实用的定义,但它本质上是循环的,因为“集合”和“集合”这两个词互相定义,并未提供严格的数学基础。

为了更清晰地理解集合,我们需要通过具体的例子来构建这个概念。


常见的集合示例

我们已经接触过一些熟悉的集合:

  • 实数集:用符号 R 表示。
  • 复数集:用符号 C 表示。
  • 整数集:用符号 Z 表示。
  • 空集:用符号 表示,它是一个不包含任何元素的特殊集合。


集合的特性

让我们通过一个具体的例子来明确集合的特性。考虑以下集合:
{π/2, 7, “Albert R”, true}

这个集合包含四个不同类型的元素:两个数字、一个字符串和一个布尔值。在数学中,集合可以包含不同类型的元素。

以下是关于集合的两个基本特性:

  1. 无序性:集合中元素的排列顺序无关紧要。例如,{π/2, 7, “Albert R”, true}{true, “Albert R”, π/2, 7}同一个集合。集合没有“第一个”或“最后一个”元素的概念。
  2. 互异性:一个元素要么在集合中,要么不在集合中,不存在“重复出现”的概念。例如,{7, π/2, 7}{7, π/2} 描述的是同一个集合,重复列出元素7并不会改变集合本身。

成员关系

集合最根本的特征是它包含哪些元素。我们用符号 来表示成员关系。

  • 公式x ∈ A 表示“元素x是集合A的成员”。
  • 示例
    • π/2 ∈ {π/2, 7, “Albert R”, true} 为真。
    • 14/2 ∈ {π/2, 7, “Albert R”, true} 也为真,因为14/2等于7。
    • π/3 ∉ {π/2, 7, “Albert R”, true} 为真,表示π/3不是该集合的成员。

“x是A的成员”也可以说成“x是A的元素”或“x在A中”,它们是同义词。

重要示例

  • 7 ∈ Z 为真(7是整数)。
  • 2/3 ∉ Z 为真(2/3不是整数)。
  • Z ∈ {true, Z, 7} 为真。这个例子表明,集合本身可以作为另一个集合的元素。集合{true, Z, 7}包含三个元素:一个布尔值、一个集合(整数集Z)和一个数字。

子集

与成员关系相关的另一个基本概念是子集。我们用符号 表示。

  • 公式A ⊆ B 表示“集合A是集合B的子集”。
  • 定义:如果集合A中的每一个元素也都是集合B的元素,那么A是B的子集。用谓词逻辑表示:∀x (x ∈ A ⇒ x ∈ B)

示例

  • Z ⊆ R:所有整数都是实数,所以整数集是实数集的子集。
  • R ⊆ C:所有实数都是复数,所以实数集是复数集的子集。
  • 考虑集合 {3, 5, 7}{3}
    • 3 ⊆ {3, 5, 7}错误的。因为3是一个元素,不是集合。
    • {3} ⊆ {3, 5, 7}正确的。因为集合{3}的唯一元素3,确实是集合{3, 5, 7}的一个元素。

两个重要推论

  1. 任何集合都是其自身的子集:A ⊆ A 总是成立。
  2. 空集是任何集合的子集∅ ⊆ B 对于任何集合B都成立。

为什么空集是任何集合的子集?
根据子集定义,我们需要证明:对于任意元素x,如果 x ∈ ∅,则 x ∈ B
由于“x ∈ ∅”这个前提条件对于任何x都是的,而一个“假的前提蕴含任何结论”的命题在逻辑上被视为。因此,整个蕴含式 (x ∈ ∅) ⇒ (x ∈ B) 对一切x都为真。这就满足了子集的定义。


描述集合的方法

对于元素较少的集合,我们可以直接列出其元素,如 {7, π/2, “Albert R”}。对于无限集,有时也可以用省略号暗示列表,如整数集 {…, -2, -1, 0, 1, 2, …}

但对于更复杂的集合(如实数集),我们需要通过元素的性质来定义它。

  • 公式{x ∈ A | P(x)}
  • 解释:这表示“所有在集合A中,且满足性质P的那些元素x所构成的集合”。竖线 | 读作“使得”或“满足”。

示例:偶数集可以定义为:
{n ∈ Z | n 是偶数}
这里,集合A是整数集Z,性质P(n)是“n是偶数”。


幂集

最后一个核心概念是幂集。一个集合A的幂集,是A的所有子集所构成的集合。

  • 公式P(A) = {B | B ⊆ A}
  • 解释:幂集P(A)本身是一个集合,它的元素是A的各种子集。

示例:设集合 A = {true, false},求其幂集 P(A)
A的子集包括:

  1. 只包含true的子集:{true}
  2. 只包含false的子集:{false}
  3. A本身:{true, false}
  4. 空集:
    因此,P({true, false}) = { ∅, {true}, {false}, {true, false} }。这是一个包含4个元素的集合。

重要关系
根据定义,对于任意集合B,有:
B ∈ P(A) 当且仅当 B ⊆ A
这意味着“B是A的幂集的成员”等价于“B是A的子集”。

示例

  • 偶数集 E ⊆ Z,所以 E ∈ P(Z)
  • 整数集 Z ⊆ R,所以 Z ∈ P(R)


本节课中,我们一起学*了集合的基础知识。我们首先了解了集合的非正式概念和常见例子,然后深入探讨了其核心特性:无序性和互异性。我们学*了表示元素与集合关系的成员符号 ∈,以及表示集合与集合关系的子集符号 ⊆,并理解了空集是任何集合子集这一重要性质。接着,我们掌握了通过性质 {x | P(x)} 来描述集合的方法。最后,我们引入了幂集的概念,即一个集合所有子集构成的集合,并理解了 B ∈ P(A) ⇔ B ⊆ A 这一关键等价关系。这些概念是后续学*函数、关系等更复杂数学结构的基础。

计算机科学的数学基础:L1.6.2:集合运算

在本节课中,我们将要学*集合的基本运算,包括并集、交集、差集和补集。我们将通过直观的韦恩图来理解这些概念,并学*如何利用命题逻辑来证明集合恒等式。

集合运算的定义

让我们定义几个熟悉且标准的集合运算。下图展示了两个集合A和B。圆圈代表集合A中的点,另一个圆圈代表集合B中的点。透镜形状的重叠区域是同时属于A和B的点,而背景区域则是属于A或B的点。这是一种通用图示,可以帮助你根据A和B对点进行分类,它被称为韦恩图。对于两个集合的情况,它非常有用;对于三个集合,情况会变得更复杂;对于四个及以上的集合,韦恩图就不那么实用了。但许多基本运算可以通过两个集合的韦恩图很好地说明,这正是我们接下来要做的。

并集

第一个运算是并集。图中洋红色区域所示的点集,就是属于A或属于B的所有点的集合。

如果我们用集合论符号或谓词表示法来定义,并集符号U代表并集运算。因此,A ∪ B被定义为那些属于A属于B的点X的集合。

你已经开始看到并集运算与命题逻辑中的“或”连接词之间的紧密联系。但请不要混淆它们。如果你对集合使用“或”,编译器会报类型错误;如果你对命题变量使用并集,编译器同样会报类型错误。因此,尽管它们看起来很相似,但请将命题运算符和集合论运算符视为截然不同的概念。

交集

下一个基本运算是交集。它指的是同时属于A和B的点,即两个集合共有的点,图中用蓝色高亮显示。

A ∩ B的定义使用了一个倒置的并集符号来表示交集。它是那些既属于A属于B的点的集合。

利用命题逻辑证明集合恒等式

让我们暂停一下,利用集合论运算与命题运算符之间的相似性。

让我们看一个集合论恒等式。我断言,无论你谈论的是哪三个集合A、B和C,这个恒等式都成立。我们将通过建立集合论运算与命题运算之间的联系来证明它。

这个恒等式说的是:A ∪ (B ∩ C) 等于 (A ∪ B) ∩ (A ∪ C)。现在,我们先不深入思考如何给出一个直观的论证,稍后我们会用一种自动化的方式推导出来。但我们可以这样记忆:并集对交集满足分配律。如果你把并集想象成乘法,交集想象成加法,那么我们得到的规则就是 A × (B + C) = (A × B) + (A × C)

同样地,如果你交换并集和交集的角色,会得到另一个分配律:交集对并集也满足分配律。不过,我们暂且只看这一个。我们试图证明并集对交集的分配律。我们该如何仅从定义出发来证明它呢?

我们将通过证明等式左右两边的集合包含完全相同的元素来完成。也就是说,如果一个元素X出现在左边描述的集合中,那么它也一定出现在右边的集合中,反之亦然。这表明左右两边的表达式定义了具有相同点集的集合。这个证明将利用我们之前讲座中证明过的一个命题等价式,即“或”对“与”的分配律:P ∨ (Q ∧ R) 等价于 (P ∨ Q) ∧ (P ∨ R)

你可以看到,这个紫色的命题等价式与蓝色的集合论等式具有相同的结构,只是并集被替换为“或”,交集被替换为“与”,集合变量A、B、C被替换为命题变量P、Q、R。请记住,我们已经证明了这个命题等价式,我们将在证明这两个集合相等的过程中用到它。

我们说过,通过证明两个集合包含相同的点来证明它们相等。以下是证明过程,它将是一个贯穿始终的“当且仅当”论证。

观察左边:一个点X属于 A ∪ (B ∩ C),根据并集的定义,当且仅当 X属于A X属于 B ∩ C。这里我只是应用了并集的定义。

现在,看表达式 X ∈ B ∩ C,这等价于 X ∈ B X ∈ C,这里应用了交集的定义。

现在我得到了一个包含“或”和“与”的命题公式,以及关于X是否属于A、B、C的基本断言。此时,我可以立即应用我的命题等价式,断言 X ∈ A ∨ (X ∈ B ∧ X ∈ C) 成立,当且仅当 (X ∈ A ∨ X ∈ B) ∧ (X ∈ A ∨ X ∈ C) 成立。

为什么?因为我只是调用了命题等价式。让我们这样看:如果我把 X ∈ A 看作命题P,把所有 X ∈ A 替换为P;把 X ∈ B 看作Q;把 X ∈ C 看作R。那么我可以看到,第一个集合论断言具有 P ∨ (Q ∧ R) 的形式,并且我可以根据命题等价式将其转换为 (P ∨ Q) ∧ (P ∨ R),然后记住P、Q、R代表什么,就能回到集合论的基本成员关系断言。

现在,我们刚刚证明了 (X ∈ A ∨ X ∈ B) ∧ (X ∈ A ∨ X ∈ C)。而这当且仅当(就像我们在左边所做的那样)X属于 A ∪ B,同样地,这里X属于 A ∪ C。然后,X 属于这个集合属于那个集合,等价于说X属于它们的交集。至此,我已经完成了证明:一个点属于左边集合,当且仅当它属于右边集合。请记住,那正是恒等式的右边。

这实际上是一个通用方法:任何涉及并集、交集以及我们稍后将讨论的差集和补集运算的集合论等式,都可以转换为命题等式或命题等价式。我们可以检查该命题断言是否是一个等价式,并通过将集合表达式中的成员关系语句转换为命题组合,来自动验证任何涉及并集、交集的集合论恒等式。事实上,像Mathematica这样的自动引擎正是通过这种方式来证明集合论恒等式的。

差集与补集

最后,为了记录完整,我们列出最后一个运算:差集运算。差集是指属于A但不属于B的元素集合。

我们将其写作 A - B,它是那些属于A不属于B的点的集合,图中用橙色高亮区域表示。

差集运算的一个特例是补集。当你知道所有集合都从属于某个整体论域时,你可以定义补集为所有不在A中的东西的集合。即集合 {X | X ∉ A},其中X被理解为在某个论域内取值。如果要用图表示,我们会看整个橙色区域,即所有不在A中的部分,如果我们把整个幻灯片看作代表论域的话。

总结

本节课中,我们一起学*了集合的四种基本运算:并集、交集、差集和补集。我们通过韦恩图直观地理解了它们的含义,并掌握了利用命题逻辑的等价关系来证明集合恒等式的重要方法。理解这些运算及其关系是深入学*集合论和计算机科学数学基础的关键一步。

计算机科学的数学基础:L1.7.1:关系 🔗

在本节课中,我们将学*数学中的一个基本概念:关系。关系是比集合更进一步的数学抽象,它在计算机科学(如数据库)和数学的许多领域(如等价关系、偏序)中都有广泛应用。我们将从直观的例子入手,逐步建立关系的正式定义,并学*如何操作和组合关系。

什么是二元关系?

在微积分中,你见过很多函数,如三角函数、有理函数、指数函数和对数函数。本节我们将从更一般的角度讨论函数,并将其视为二元关系的一个特例。

一个二元关系是一个数学对象,它将一个称为定义域的集合中的元素,与另一个称为陪域的集合中的元素关联起来。关系是继集合之后最基本、最重要的数学抽象之一。

关系的例子:注册关系

让我们看一个贴*生活的例子:“注册”关系。这个关系关联着学生(定义域)和课程(陪域)。

  • 定义域 (D): 学生集合
  • 陪域 (J): 课程集合
  • 关系 (R): “注册”关系,用箭头表示。例如,箭头从 Jason 指向 6.042,表示 Jason 注册了 6.042 这门课。

关系的表示方法

有多种方式表示一个关系:

  • 中缀表示法: Jason R 6.042
  • 前缀表示法: R(Jason, 6.042)
  • 有序对表示法: 关系 R 可以看作是一组有序对的集合,例如 (Jason, 6.042)R 的一个元素。这组有序对的集合称为关系的

关系的像

关系的一个核心概念是。你可以把关系看作一个“操作符”,作用于定义域中的元素(或元素集合)。

  • 单个元素的像: R(Jason) 表示 Jason 注册的所有课程。根据上图,R(Jason) = {6.042, 6.001}
  • 集合的像: 如果 X 是学生的一个子集,那么 R(X) 表示 X任何学生所注册的所有课程的集合。

例如,R({Jason, Eva}) 就是 Jason 或 Eva 注册的课程。从图中看,Jason 注册了 {6.042, 6.001},Eva 注册了 {6.001, 6.004}。因此,R({Jason, Eva}) = {6.042, 6.001, 6.004}

像的正式定义

用集合论的语言可以更精确地定义像:
R(X) = { j ∈ J | ∃ d ∈ X, d R j }
这个公式的意思是:R(X) 是所有满足以下条件的课程 j 的集合:存在某个学生 d 属于集合 X,并且 dj 有关系 R(即 d 注册了 j)。

关系的逆

我们可以对关系进行一种操作,得到它的逆关系,记作 R⁻¹。逆关系就是将原关系的箭头方向全部反转。

对于“注册”关系 R,其逆关系 R⁻¹ 可以理解为“被...注册”关系。例如,如果 Jason R 6.042(Jason注册了6.042),那么就有 6.042 R⁻¹ Jason(6.042被Jason注册)。

逆像

利用逆关系,我们可以定义逆像R⁻¹(Y) 表示所有注册了集合 Y任何一门课程的学生。

例如:

  • R⁻¹({6.001}) = {Jason, Eva} (注册了6.001的学生)
  • R⁻¹({6.003, 6.001}) = {Jason, Joan, Eva} (注册了6.003或6.001的学生)

逆像可以用来简洁地表达关于数据库的断言。例如,语句“所有学生都至少注册了一门课”可以写成:
D ⊆ R⁻¹(J)
其中 D 是所有学生的集合,J 是所有课程的集合。这个包含关系断言:每个学生(D 中的元素)都至少与一门课程(J 中的某个元素)通过 R 相关联,因此也就在 R⁻¹(J) 中。

关系的复合

关系可以像函数一样进行复合。假设我们有两个关系:

  • V: “指导”关系,从教授关联到学生(教授 P 指导学生 D)。
  • R: “注册”关系,从学生关联到课程(学生 D 注册课程 J)。

那么,复合关系 R ∘ V 表示“有指导关系”后接“有注册关系”。它从教授关联到课程,其含义是:教授 P 指导的某位学生注册了课程 J

复合关系的计算与定义

计算 (R ∘ V)({FTL, TLF}) 的步骤:

  1. 先计算 V({FTL, TLF}),得到这两位教授指导的所有学生,假设是 {Joan, Eva, Adam}。
  2. 再计算 R({Joan, Eva, Adam}),得到这些学生注册的所有课程,例如 {6.003, 6.001, 6.004}。

因此,(R ∘ V)({FTL, TLF}) = {6.003, 6.001, 6.004}

复合关系的正式定义是:
P (R ∘ V) J ⇔ ∃ d, (P V d) ∧ (d R J)
这个公式的意思是:教授 P 与课程 J 具有 R ∘ V 关系,当且仅当存在一个学生 d,使得 P 指导 d,并且 d 注册了 J

关系的集合运算与断言

关系本身是有序对的集合,因此可以对它们进行集合运算(如交集、并集、补集)。这让我们能够简洁地表达复杂的规则或查询。

假设我们还有另一个关系:

  • T: “授课”关系,从教授关联到课程(教授 P 教授课程 J)。

现在,我们想表达一条规则:“教授不应教授自己指导的学生的课程”。用逻辑语言描述是:对于任何教授 P 和课程 J,不能同时有 P (R ∘ V) J(P有学生注册J)和 P T J(P教授J)。

利用集合运算,这个规则可以极其简洁地表达为:
T ∩ (R ∘ V) = ∅
即,“授课”关系 T 与“指导学生的注册”关系 R ∘ V 没有共同的有序对。等价地,也可以写成:
(R ∘ V) ⊆ ¬T
即,R ∘ V 关系中的所有配对,都不在 T 关系中。

关系的正式定义与函数

现在,让我们更正式地定义二元关系。一个从集合 A 到集合 B 的二元关系 R,包含三部分:

  1. 定义域 A
  2. 陪域 B
  3. 一个由有序对 (a, b) 组成的集合,其中 a ∈ A, b ∈ B。这个集合称为关系的,它精确描述了哪些元素被关联起来。
  • 值域: 关系 R值域是指陪域 B实际A 中元素关联到的那些元素组成的集合,即 R(A)。值域通常是陪域的一个子集。

函数是特殊的关系

函数是一种特殊的二元关系,它要求定义域中的每个元素,最多与陪域中的一个元素相关联。

  • 用像的语言描述:对于所有 a ∈ Af(a) 这个集合的大小 ≤ 1
  • 用关系的语言描述:如果 a f ba f b‘,那么必然有 b = b’

换句话说,在函数的关系图中,定义域每个点发出的箭头数不能超过一个(可以为0,即未定义)。这使得每个输入值都对应唯一确定的输出值(如果存在的话)。

总结

本节课我们一起学*了二元关系这一核心数学概念。

  • 我们首先通过“注册”的例子直观理解了关系如何关联两个集合的元素。
  • 然后学*了关系的逆像,它们用于描述关系如何作用于元素或集合。
  • 接着,我们探讨了关系的复合操作,它允许我们将多个关系链式组合。
  • 我们还看到,关系作为集合,可以进行交集等运算,从而简洁地表达复杂的逻辑断言。
  • 最后,我们给出了关系的正式集合论定义,并明确了函数是“每个输入至多有一个输出”的特殊关系。

理解关系是学*后续更复杂的数学结构(如等价关系、偏序)以及数据库理论的重要基础。

MIT 6.042J:P18:L1.7.3- 关系映射属性

在本节短片中,我们将讨论一些关系属性,这些属性被称为映射属性,也可称为关系的“箭头”属性。本节内容主要是词汇介绍,包含该领域标准且学*离散数学必须了解的六七个概念。这些概念的应用将在下一节短片开始,届时我们将把这些属性应用于计数问题,尽管本节末尾也会有一个关于计数的关键结论。

现在,让我们继续。请记住,一个二元关系由三部分组成:一个定义域(图中用A表示)、一个陪域(图中用B表示)以及定义域元素与陪域元素之间的关联关系,由箭头表示,这些箭头被称为关系的图。

我们已经观察过箭头的一个方面,即函数的概念可以通过“每个定义域元素最多只有一个箭头射出”来描述。这意味着从一个定义域点出发的箭头有唯一确定的另一端,称为该点在该关系下的值,这实际上就是一个函数f。例如,f(绿色) = 品红色,表示有一个箭头从绿色元素射出。

但在本图中,并非每个定义域元素(并非每个绿点)都有箭头射出,这是典型情况。因此,这将是一个部分函数的示例,其中f(绿色元素)并不总是有定义(如果没有箭头射出)。

关系的一般概念延续了这个函数思想。基本上,我们将根据定义域元素射出的箭头数量对关系进行分类,主要有三类:每个定义域元素最多射出一个箭头的关系、每个定义域元素恰好射出一个箭头的关系,以及每个定义域元素至少射出一个箭头的关系。

对称地,我们也将以同样的方式根据陪域元素射入的箭头数量对关系进行分类:每个陪域元素至少有一个箭头射入、恰好有一个箭头射入,或最多有一个箭头射入。这些分类的各种组合有标准的名称,事实证明你需要了解它们。接下来我们将逐一介绍。

全关系

全关系意味着每个定义域元素至少有一个箭头射出。观察此图,它目前还不是全关系,因为有两个绿色定义域元素没有箭头射出(已用红色高亮显示)。我们可以通过移除它们来修正。现在,我们得到了一个全关系:每个定义域元素至少有一个箭头射出。

另一种表述“全”的方式是:如果你观察陪域的逆像,它等于整个定义域。这意味着,如果你取出所有从定义域射出的箭头,将它们反转方向,然后观察所有有箭头指向的元素,结果就是整个定义域。用关系运算符和集合来表示就是:关系R是全的,当且仅当 R^{-1}(B) = A

全函数

全函数意味着每个定义域元素恰好有一个箭头射出。这可能是函数中最常见的情况,许多领域直接假设函数是全的。但事实是,函数常常不是全的,而人们对此并不总是很仔细。

让我们看一个类似微积分的例子。这里有一个函数G,它取一对实数并返回一个实数,将实数*面映射到实数线。其定义是 G(x, y) = 1 / (x - y)

现在,这个函数G的定义域实际上是所有实数对(这就是“从R×R(简写为R²)到陪域R”的含义),陪域是所有实数的集合。但这个G显然不是全函数,因为1/0无定义,这意味着在45度线上,G无定义。因此,G实际上不是一个全函数,尽管它很常见,而你通常不会担心部分函数,所以你可能不会注意到它是部分的,因为你不*惯关注这一点。

让我们看一个稍作修改的版本。这是函数G₀,它从一个稍后指定的未指定定义域映射到实数。它具有完全相同的公式 G₀(x, y) = 1 / (x - y)。但现在我要告诉你,定义域不再是所有实数,而是去掉了那条45度线的实数集。我想去掉那些坏点,不再担心它们。一旦我这样做,我就得到了两个具有相同图但不同定义域的关系。结果是,我从G的定义域中移除了所有坏点,剩下的是一个全函数G₀。

满射

满射是一种关系,其中陪域B中的每个点至少有一个箭头射入。同样,在这张图中,这一点并不完全成立,因为至少有一个坏点(用红色标出)没有箭头射入。让我们再次通过移除它来修正。现在我得到了一个满射关系或满射,因为实际上陪域B中的每个元素都至少有一个箭头射入,每个元素都是某个箭头的终点。

同样,我们可以用集合运算来表示:关系R是满射,当且仅当定义域A的像等于陪域B,即 R(A) = B。另一种说法是,当且仅当函数的值域等于其整个陪域。请记住,值域是被映射到的点的集合,即R(A)。它并不总是等于陪域,但当它等于时,就构成了满射。

单射

单射是关系的另一种变体,它要求陪域中的每个元素最多有一个箭头射入。观察此图,它目前还不是单射,因为这里至少有两个点有超过一个箭头射入,这使它无法成为单射。让我们通过删除几条造成拥挤的边来修正。现在我得到了一种情况,实际上B中的每个元素最多只有一个箭头射入,因此我向你展示了一个单射的图示。

双射

最后一个概念是当你拥有所有良好属性时:双射要求每个定义域元素恰好有一个箭头射出,且每个陪域元素恰好有一个箭头射入。它是一个既是单射又是满射的全函数,因为它对定义域和陪域都满足“至少一个”、“至多一个”且最终“恰好一个”的条件。

关于双射,有一个显而易见的结论,我们将以此结束本节,这也是它们在计数理论中有用的原因。因为很明显,既然A中每个元素恰好射出一个箭头,那么箭头的数量就等于A的大小。同样,既然B中每个元素恰好有一个箭头射入,那么箭头的数量就等于B的大小。这意味着,当存在一个双射时,两个集合的大小相等。如果两个有限集合A和B之间存在一个双射,那么 |A| = |B|

总结

在本节中,我们一起学*了关系的几种关键映射属性:全关系、全函数、满射、单射和双射。我们了解了如何根据定义域元素射出箭头和陪域元素射入箭头的数量来定义和区分这些属性。最后,我们看到了双射在计数中的一个基本应用:两个集合间若存在双射,则它们的大小相等。下一节我们将开始应用这些属性进行具体的计数分析。

计算机科学的数学基础:P19:L1.7.5- 有限集合的基数 📊

在本节课中,我们将学*如何将集合之间的映射性质与计数性质联系起来。我们将从双射的基本概念出发,探讨如何利用映射来证明集合的大小关系,并最终得出一些重要的计数规则。


映射与计数

上一节我们介绍了双射、满射和单射的概念。本节中,我们来看看这些映射如何帮助我们确定有限集合的大小。

首先,我们重申一个基本观点:如果存在从一个有限集合 A 到另一个有限集合 B 的双射,那么 AB 的大小相同。我们用 |A| 表示集合 A 的大小(即元素个数)。


幂集大小的计算

让我们立即应用双射的思想来解决一个具体问题:如何计算一个有限集合的幂集(所有子集的集合)的大小?

假设我们不知道答案。我们要求的是 A 的幂集 P(A) 的大小。例如,如果集合 A 有三个元素 {a, b, c},那么它的幂集包含:

  • 1个空子集
  • 3个单元素子集:{a}, {b}, {c}
  • 3个双元素子集:{a, b}, {a, c}, {b, c}
  • 1个三元素子集:{a, b, c}
    总计 8 个子集。

现在,让我们进行一般性的论证。假设集合 An 个元素,我们将其编号为 a₀, a₁, ..., aₙ₋₁。考虑 A 的任意一个子集 S

我们可以为这个子集 S 构造一个长度为 n 的二进制位串(比特串)。构造规则如下:

  • 如果元素 aₖ 在子集 S 中,则位串的第 k 位为 1
  • 如果元素 aₖ 不在子集 S 中,则位串的第 k 位为 0

公式位串的第k位 = 1 当且仅当 aₖ ∈ S

这个规则清晰地定义了子集与位串之间的一个双射:

  • 给定一个子集,我们可以唯一地确定一个位串。
  • 给定一个位串,我们可以唯一地确定一个子集。

因此,根据双射定理,n 位二进制串的数量等于幂集 P(A) 的大小。每个计算机科学家都知道,长度为 n 的二进制串总共有 2ⁿ 个。

由此我们得到了著名的公式:
公式|P(A)| = 2^{|A|}


更多计数规则:映射引理

除了双射规则,我们还可以根据映射是满射或单射来推导集合大小之间的不等式关系。

以下是基于映射性质的计数规则:

满射规则:如果存在从集合 A 到集合 B 的满射函数,那么对于有限集合 AB,有 |A| ≥ |B|

  • 推理:满射要求 B 中每个元素至少有一个箭头射入,所以箭头总数至少为 |B|。函数要求每个 A 中元素至多射出一个箭头,所以箭头总数至多为 |A|。因此 |A| ≥ 箭头数 ≥ |B|

单射规则:如果存在从集合 A 到集合 B 的全单射关系(或函数),那么对于有限集合 AB,有 |A| ≤ |B|

  • 推理:单射要求 B 中每个元素至多有一个箭头射入,所以箭头总数至多为 |B|。全关系要求每个 A 中元素至少射出一个箭头,所以箭头总数至少为 |A|。因此 |A| ≤ 箭头数 ≤ |B|

关系的定义与映射引理

我们可以定义三种表示集合间大小比较的二元关系:

  1. A bij B:表示存在从 AB 的双射。
  2. A surj B:表示存在从 AB 的满射函数。
  3. A inj B:表示存在从 AB 的全单射关系。

根据我们刚才的论证,对于有限集合,这些关系等价于集合大小的比较:

  • A bij B 当且仅当 |A| = |B|
  • A surj B 当且仅当 |A| ≥ |B|
  • A inj B 当且仅当 |A| ≤ |B|

这个结论被称为映射引理。它将抽象的映射存在性问题,转化为了具体的集合大小比较问题。


从有限到无限的思考

映射引理是针对有限集合证明的。对于无限集合,“大小”的概念变得复杂。然而,我们可以探究这些关系本身的性质是否在无限集合中依然成立。

以下是三个基于关系传递性的命题:

  1. 如果 A bij BB bij C,那么 A bij C。(双射的复合仍是双射)
  2. 如果 A surj BB surj C,那么 A surj C。(满射的复合仍是满射)
  3. 如果 A surj BB surj A,那么 A bij B

对于有限集合,这些命题直接从映射引理得出。对于无限集合:

  • 命题1和2很容易证明,只需使用映射复合的性质。
  • 命题3则非显然,它是一个重要的定理,称为施罗德-伯恩斯坦定理。我们将在后续课程中遇到它。

总结

本节课中我们一起学*了:

  1. 利用双射证明集合等势,并以此推导出幂集大小的公式:|P(A)| = 2^{|A|}
  2. 利用满射和单射的性质,得到了比较有限集合大小的映射规则(|A| ≥ |B||A| ≤ |B|)。
  3. 引入了 bijsurjinj 三种关系,并总结了映射引理,该引理将这些关系与有限集合的基数比较等价起来。
  4. 初步探讨了这些关系性质在无限集合中的延伸,并指出了施罗德-伯恩斯坦定理的重要性。

这些工具将帮助我们在后续学*中,以更严谨和巧妙的方式处理与计数和集合大小相关的问题。

计算机科学的数学基础:P20:L1.8.1:归纳法 🧮

在本节课中,我们将要学*数学归纳法。归纳法是证明关于非负整数命题的一种强大工具。我们将从基本概念开始,通过一个简单的例子理解其原理,然后学*一个标准的证明模板,并应用它来证明一个几何求和公式。最后,我们将通过一个有趣的铺砖问题,展示如何通过证明一个更强的命题来简化归纳证明。

归纳法的基本概念

上一节我们介绍了课程概述,本节中我们来看看归纳法的核心思想。归纳法的概念可以这样解释:假设我们计划为非负整数分配颜色。

例如,我们定义一种颜色分配规则:

  • 0是蓝色。
  • 1是红色。
  • 2是蓝色。
  • 3是红色。
  • 4是绿色。
  • 5是绿色。
  • ……

现在,我描述我心目中的颜色规则,看看你能否推断出结果。规则如下:

  1. 0不是红色。
  2. 如果一个整数紧挨着一个红色整数,那么它也是红色。

根据这些规则,你可以推断出所有整数都不是红色。这实际上体现了归纳法的思想。

抽象地陈述归纳法规则:假设你有一个关于数的性质 R(例如“是红色”)。如果满足以下两个条件:

  1. 基础步骤R(0) 为真(0具有性质R)。
  2. 归纳步骤:对于任意非负整数 n,如果 R(n) 为真,那么 R(n+1) 也为真。

那么,你可以得出结论:对于所有非负整数 mR(m) 都为真。

使用量词可以简洁地表示为:

  • 前提R(0) ∧ (∀n. R(n) ⇒ R(n+1))
  • 结论∀m. R(m)

请注意,前提中的变量 n 和结论中的变量 m 是相互独立的局部变量,可以任意命名。

有时归纳法可以用多米诺骨牌来比喻:推倒第一块骨牌(基础步骤),并确保每一块倒下的骨牌都能推倒下一块(归纳步骤),那么所有骨牌都会倒下。

归纳法证明模板与应用

上一节我们介绍了归纳法的逻辑规则,本节中我们来看看如何具体地使用归纳法进行证明。我们将通过证明几何求和公式来演示一个标准的证明模板。

定理:对于任意实数 r ≠ 1 和非负整数 n,有:
∑_{i=0}^{n} r^i = (r^{n+1} - 1) / (r - 1)

以下是使用归纳法证明的步骤模板:

证明(对 n 进行归纳):

  • 归纳假设 P(n):等式 ∑_{i=0}^{n} r^i = (r^{n+1} - 1) / (r - 1) 成立。
  • 基础步骤(证明 P(0) 成立):
    n = 0 时,左边和为 r^0 = 1
    右边为 (r^{0+1} - 1) / (r - 1) = (r - 1) / (r - 1) = 1
    因此,P(0) 成立。
  • 归纳步骤(证明 P(n) ⇒ P(n+1)):
    假设 P(n) 对某个 n ≥ 0 成立,即:
    ∑_{i=0}^{n} r^i = (r^{n+1} - 1) / (r - 1)。 (归纳假设)
    我们需要证明 P(n+1) 成立,即:
    ∑_{i=0}^{n+1} r^i = (r^{(n+1)+1} - 1) / (r - 1) = (r^{n+2} - 1) / (r - 1)
    从左边开始推导:
    ∑_{i=0}^{n+1} r^i = (∑_{i=0}^{n} r^i) + r^{n+1}
    将归纳假设代入:
    = (r^{n+1} - 1) / (r - 1) + r^{n+1}
    将第二项通分:
    = (r^{n+1} - 1) / (r - 1) + (r^{n+1}(r - 1)) / (r - 1)
    合并分子:
    = (r^{n+1} - 1 + r^{n+2} - r^{n+1}) / (r - 1)
    化简:
    = (r^{n+2} - 1) / (r - 1)
    这正是 P(n+1) 的右边。因此,P(n+1) 成立。
    由归纳法可知,对于所有非负整数 nP(n) 成立。∎

这个模板清晰地组织了证明的结构:声明证明方法、明确归纳假设、验证基础情况、利用归纳假设完成归纳步骤。

强化归纳假设:铺砖问题 🧱

上一节我们掌握了标准的归纳证明,本节中我们来看一个需要技巧的例子。有时直接证明一个命题很困难,但通过证明一个更强的命题,反而能让归纳证明变得更容易。

问题描述:有一个 2^n × 2^n 的广场,由单位正方形组成。我们需要用“L”形瓷砖(由3个单位正方形组成)铺满整个广场,但正中心留出一个单位正方形的位置放置雕像。

初始尝试:尝试直接对 n 进行归纳。

  • 归纳假设 P(n):可以铺满 2^n × 2^n 的广场,并让雕像在中心。
  • 基础步骤 n=01×1 广场,直接把雕像放进去,无需铺砖,成立。
  • 归纳步骤:假设 P(n) 成立,考虑 2^{n+1} × 2^{n+1} 的广场。它可以被分成4个 2^n × 2^n 的象限。我们希望雕像在整体广场的中心,但根据归纳假设,我们只能保证在每个小象限的中心放置雕像。这无法直接拼合成一个完整的、中心留空的铺砖方案。我们卡住了。

解决方案:证明一个更强的命题。

  • 强化归纳假设 Q(n):对于 2^n × 2^n 的广场,无论指定哪一个单位正方形留空,我们都能用L形瓷砖铺满其余部分。
  • 基础步骤 n=01×1 广场,唯一的正方形就是被指定的留空位置,自然铺满(零块瓷砖),成立。
  • 归纳步骤:假设 Q(n) 成立。考虑一个 2^{n+1} × 2^{n+1} 的广场,并指定任意一个单位正方形留空(如图中紫色方块)。
    1. 将大广场分成4个 2^n × 2^n 的象限。
    2. 留空方块必然位于其中一个象限内(例如右上象限)。根据强化归纳假设 Q(n),我们可以铺满这个右上象限,并精确地在指定位置留空。
    3. 对于其他三个象限,我们在每个象限中指定靠*大广场中心的那一个角作为留空位置(如图中三个蓝色方块)。再次根据 Q(n),我们可以铺满这三个象限。
    4. 现在,大广场中心区域恰好有三个留空的单位正方形(来自三个象限的角),它们形成一个“L”形。我们只需用一块L形瓷砖覆盖这个位置。
    5. 至此,整个 2^{n+1} × 2^{n+1} 的广场已被L形瓷砖铺满,且最初指定的正方形留空。Q(n+1) 得证。

通过证明“可以在任意指定位置留空”这个更强的性质 Q(n),我们在归纳步骤中拥有了更大的灵活性(可以自由指定子象限中的留空位置),从而巧妙地构造出了整体的铺砖方案。这个证明过程也隐含地给出了一个递归算法来生成铺砖图案。


本节课中我们一起学*了数学归纳法。我们从其基本逻辑原理出发,学*并应用了一个清晰的证明模板来证明几何求和公式。最后,我们通过有趣的铺砖问题,掌握了“强化归纳假设”这一重要技巧,即通过证明一个更强的命题来简化归纳证明过程。归纳法是计算机科学中分析递归算法、证明程序正确性的基石,务必熟练掌握。

计算机科学的数学基础:L1.8.2:伪归纳法 🐎

在本节课中,我们将学*如何识别证明中的错误。我们将通过分析一个经典的“伪归纳法”证明来练*这项技能。这个证明试图论证一个明显荒谬的结论:所有的马都具有相同的颜色。

理解证明包括识别其中错误的能力。为了测试这项技能以及你对归纳法的理解,我将展示一个伪归纳法证明。我将证明一个明显荒谬的命题,即所有的马都具有相同的颜色,比如它们都是黑色的。

我将通过归纳法来证明这一点。首先,定理中没有提到数字n,这在各种需要归纳证明的问题中很常见。因此,我需要用n来重新表述它。证明将基于n进行归纳。

归纳假设是:任何恰好由n匹马组成的集合,其中的马都具有相同的颜色。

现在开始证明。我将使用基础情况n=1,因为我不想用n=0(即没有马)这种可能引起你怀疑基础情况是否作弊的方式来分散你的注意力。实际上,从n=0开始论证空集中的所有马颜色相同是完全合理的,因为空集中没有任何东西。但我们不深入讨论这一点。

我们从n=1开始。确实,如果你看任何由1匹马组成的集合,这匹马的颜色和它自己相同。我实际上已经证明了基础情况n=1。

现在继续。在归纳步骤中,我可以假设任意n匹马具有相同的颜色,其中n是任何大于或等于0的数。此时,学生可能会抱怨这不公*,因为你已经假设了错误的东西,这很荒谬。是的,这很荒谬,但这不应该是问题所在。我只是被允许假设一个归纳假设。我只需要证明P(n)蕴含P(n+1)。既然结论荒谬,那么证明过程一定存在问题。

让我们看看证明是否存在问题。再次强调,我假设任何n匹马的集合都具有相同的颜色。我必须证明任何n+1匹马的集合都具有相同的颜色。

我将如何证明呢?假设有一个n+1匹马的集合。让我们考虑这个集合中的前n匹马。根据归纳假设,前n匹马具有相同的颜色,比如是黑色。

同样,根据归纳假设,第二组n匹马(即除了第一匹马之外的所有马)也具有相同的颜色。

这告诉我,第一匹马和最后一匹马与中间所有的马具有相同的颜色。因此,事实上它们都具有相同的颜色。证明完毕。

所以,这里肯定有错误。错误在于,证明P(n)蕴含P(n+1)的过程是错误的。它看起来正确,但P(n)蕴含P(n+1)的证明必须对所有大于或等于基础情况的n都成立。如果你仔细看这个证明,它在基础情况n=1,并试图通过蕴含关系从基础情况推导到n=2时,并不成立。

因此,证明在n=1的情况下失效了。当我们试图证明P(1)蕴含P(2)时,我们的论证发生了什么?在这种情况下,没有“中间的马”。n+1等于2,所以有一匹“第一匹马”(这就是前n匹马),而第二组n匹马就是另一匹马。没有一匹它们共同拥有颜色的“中间的马”。所以证明就在这里失效了。

你可能没有注意到,因为这是唯一失效的地方。这是一个我们被省略号误导的例子。因为我画了n+1匹马,中间用省略号表示有很多马,看起来好像有中间的马,但实际上没有。

这个伪证明的关键点在于,它唯一的谬误是当n=1时不成立。但对于证明“如果所有两匹马的集合颜色相同,则蕴含所有三匹马的集合颜色相同”这一点,它确实是成立的。这又是一个“假命题蕴含任何命题”的例子。但即使在这里,证明在逻辑上也是成立的。然而,如果证明在某个环节断裂,就像多米诺骨牌链中缺少了一块,整个论证就会失败。

本节课中,我们一起学*了如何通过分析一个伪归纳法证明来识别逻辑谬误。我们看到了一个试图证明“所有马颜色相同”的错误论证,并指出了其归纳步骤在从n=1推导到n=2时失效的关键点。理解归纳法证明的完整性至关重要,必须确保基础情况正确,且归纳步骤对所有n≥基础情况都有效。

计算机科学的数学基础:L1.8.4:强归纳法 🔍

在本节课中,我们将学*一种有趣的归纳法变体——强归纳法。我们将了解其定义、直观理解,并通过两个具体例子来掌握其应用方法。

强归纳法的定义与原理

现在,我们来看一种有趣的归纳法变体,称为强归纳法。它的工作原理如下。

与普通归纳法一样,强归纳法也需要证明基础情况 P(0)。我们的目标是证明对于所有 nP(n) 都成立。因此,我们先证明 P(0)

但在归纳步骤中,为了证明 P(n+1),普通归纳法只假设 P(n) 成立。而强归纳法则允许我们假设从 P(0)P(n) 的所有性质都成立。也就是说,我们可以假设所有小于等于 n 的数都具有该性质。

从这些假设出发,我们最终可以得出结论:对于所有 nP(n) 都成立。

一个直观的理解方式是:归纳法的过程就像从0开始,一步步走到1、2、3……。从 nn+1 的归纳步骤证明了每一步的合理性。当你到达 n 并需要证明能到达 n+1 时,你已经走过了从0到 n 的所有步骤。与其只记住最后一步,不如充分利用你已经走过的所有步骤这一事实。

这是一个直观的、非形式化的论证,其形式化证明将在下一节中展开。我们暂时接受它作为一个基本的数学原理,并加以运用。

应用一:邮票问题 💌

作为强归纳法的一个应用,让我们来证明一个之前用良序原理证明过的命题。事实上,强归纳法和良序原理是密切相关的,我们稍后会讨论这一点。

我们要证明:使用3分和5分的邮票,你可以凑出任何大于等于8分的邮资。

我们将通过强归纳法来证明,归纳假设 P(n) 为:我可以凑出 n+8 分的邮资。显然,如果我能证明对于所有 nP(n) 都成立,那么我就证明了对于任何大于等于8分的邮资,我都能凑出来。

以下是证明步骤:

基础情况:证明 P(0),即能否凑出8分邮资?当然可以,一张3分邮票加一张5分邮票即可。

归纳步骤:我需要证明 P(n+1)。我被允许假设对于从 n 到 0 的任何 m,我都能凑出 m+8 分邮资,而不仅仅是假设能凑出 n+8 分。我的目标是凑出 (n+1)+8 分,即 n+9 分邮资。

因此,我可以假设我能凑出从8分到 n+8 分的任何邮资。我的目标是凑出 n+9 分。

归纳步骤实际上需要根据 n 的值分成几种情况来处理。我需要证明对于所有 n,都能凑出 n+9 分。

  • 如果 n = 0,我需要凑出9分。这可以用三张3分邮票完成。
  • 如果 n = 1,我需要凑出10分。这可以用两张5分邮票完成。

现在,我的任务是凑出 n+9 分,其中 n ≥ 2n 大于等于2的好处是,如果我从中减去2,会得到一个更小的非负数。这意味着,根据强归纳法假设,我可以凑出 (n-2)+8 分的邮资。

那么,如何得到 n+9 分呢?很简单,在已经凑出的 (n-2)+8 分邮资基础上,再加一张3分邮票即可。这样就得到了 n+9 分。

这完成了归纳步骤的证明,从而整个定理得证。我们可以得出结论:对于所有 n,你确实可以使用3分和5分邮票凑出 n+8 分邮资。

应用二:拆积木游戏 🧱

让我们看另一个例子。这是一个我们过去在课堂上玩的游戏。

你从一堆积木开始,比如10块积木。你被允许进行一种操作:将一堆积木分成两堆较小的积木。如果一堆积木的高度是 a + b,你可以将其分成高度为 a 的一堆和高度为 b 的一堆。这次操作你会得到一个分数:a × b。然后你继续操作,直到无法再进行任何操作为止(即所有剩下的都是一块积木的堆)。你的最终总分是你在整个过程中获得的所有分数之和。

在课堂上,学生们会尝试各种策略。最简单的策略(可能不是最好的)是每次只拿掉一块积木。从一堆高度为 n 的积木开始,如果你采用这种“一次一块”的过程,那么你的分数将是 (n-1) + (n-2) + ... + 2 + 1

另一种更具计算机科学精神的策略可能是不断对半拆分。例如,将一堆高度为 n 的积木分成两个高度为 n/2 的堆,然后继续拆分,每次都尽可能均匀地拆分。

有趣的是,无论尝试哪种策略,最终得分都是一样的。这就是我们现在要证明的:任何拆分 n 块积木的方法都会得到相同的分数

我们知道,一次拿掉一块积木的简单策略的分数是 1 到 n-1 的和,这个和有一个漂亮的公式:n × (n-1) / 2

因此,我们可以提出我们的论断:无论你如何玩这个拆积木游戏,只要初始堆大小为 n,你的最终分数都将是 n × (n-1) / 2

我们将通过强归纳法来证明这一点,归纳假设 C(n) 就是这个论断。

基础情况n = 0。没有积木,分数为0,公式计算结果也是0,成立。

归纳步骤:我需要假设对于所有高度小于等于 n 的堆,分数公式 C(k) 都成立。然后证明对于一个高度为 n+1 的堆,其分数是 (n+1) × n / 2

我将归纳步骤分为两种情况来处理:

  1. 情况一:n+1 = 1。如果堆的高度为1,则无法进行任何操作,分数为0。公式计算结果也是0。因此,在这种情况下,C(n+1) 成立。
  2. 情况二:n+1 > 1。这是有趣的情况,因为现在可以进行操作了。既然 n+1 大于1(即至少为2),我可以将其拆分成两个堆。假设我将大小为 n+1 的堆拆分成一个 a 堆和一个 b 堆,其中 a + b = n+1

那么我的分数会是多少呢?首先,这次拆分操作的得分是 a × b。剩下的游戏就是在 a 堆和 b 堆上分别进行。由于 ab 都小于 n+1(即小于等于 n),根据强归纳假设,无论我如何在 a 堆上玩,最终得分都将是 a × (a-1) / 2;同样,在 b 堆上的最终得分是 b × (b-1) / 2

因此,我在 a+b 堆上的总得分将是:
a×b + [a×(a-1)/2] + [b×(b-1)/2]

化简这个表达式,最终可以得到 ((a+b) × ((a+b)-1)) / 2,这正好等于 (n+1) × n / 2。这正是我们要证明的 C(n+1)

至此,归纳步骤完成。我们证明了无论你如何拆分 n 块积木,最终得分总是 n × (n-1) / 2

总结 📝

本节课中,我们一起学*了强归纳法。我们首先了解了其定义:在证明 P(n+1) 时,不仅可以假设 P(n) 成立,还可以假设所有 P(0), P(1), ..., P(n) 都成立。我们通过“邮票问题”和“拆积木游戏”两个生动的例子,实践了如何运用强归纳法来证明命题。这两个例子展示了强归纳法在假设更“强”的前提下,如何简化证明过程,特别是在问题可以自然地分解为涉及更小规模子问题的情况时。

计算机科学的数学基础:L1.8.6:良序原理与归纳法对比 🧮

在本节课中,我们将要学*普通归纳法、强归纳法与良序原理之间的关系。我们将看到,尽管它们在表述上有所不同,但在逻辑上是等价的。理解这一点有助于我们在证明时选择最清晰、最合适的表述方式。


普通归纳法与强归纳法的关系

上一节我们介绍了归纳法的基本形式。本节中我们来看看普通归纳法与强归纳法之间的具体联系。

首先,普通归纳法是强归纳法的一个特例。在普通归纳法中,我们只假设 P(n) 成立来证明 P(n+1)。而在强归纳法中,我们可以假设对于所有 k ≤ nP(k) 都成立,来证明 P(n+1)。但你在强归纳法中并不一定要使用所有额外的假设,你可以只使用 P(n)。因此,任何普通归纳法都可以被视为强归纳法的一个特例。

以下是两种归纳法的核心假设对比:

  • 普通归纳法:假设 P(n) 为真,证明 P(n+1) 为真。
  • 强归纳法:假设对于所有 k ≤ nP(k) 为真,证明 P(n+1) 为真。

那么,为什么还要区分它们呢?主要原因在于表述的清晰度。使用普通归纳法可以让读者清楚地知道,对 n+1 情况的证明仅依赖于 n 的情况,而不是像典型的强归纳法证明那样依赖于所有小于等于 n 的情况。此外,有人认为从 nn+1 的推理比从“所有小于等于 n 的情况”到 n+1 的推理更直观。


将强归纳法转化为普通归纳法

一个有趣且可能令人惊讶的观点是:我们总是可以使用普通归纳法。那么,如何用普通归纳法来替代强归纳法呢?方法很简单。

假设你使用强归纳法证明了对于所有 mP(m) 成立,其归纳假设是对于所有 k ≤ nP(k) 成立。现在,我们定义一个新的性质 Q(n)

Q(n) 定义为:对于所有 k ≤ nP(k) 成立。

通过将归纳假设修改为包含这个全称量词“对于所有 k ≤ n”,原本对 P(k) 的强归纳法就变成了对 Q(n) 的普通归纳法。我们只需对公式进行一些简单的符号修饰,就可以将强归纳法转化为普通归纳法。

由此可见,强归纳法并没有提供超越普通归纳法的新能力。它只是让你省略了在使用普通归纳法时必须明确写出的一连串全称量词。使用强归纳法的原因正是因为它更简洁,你不必到处重复书写“对于所有 k ≤ n”这样的语句。


良序原理与归纳法的关系

现在我们来看最后一个问题:良序原理与归纳法之间有什么关系?本质上,它们是同一回事。

你可以轻松地将一个归纳法证明的模板,转化为一个良序原理证明的模板,反之亦然。虽然我们不深入探讨具体转换的细节,但这个过程是常规的。由此可知,良序原理并没有为任何给定的证明增加新的数学能力或提供新的视角。它只是组织和讲述同一个故事的不同方式。

这也意味着,从概念上讲,这些表面上不同的推理规则——普通归纳法、强归纳法、良序原理——实际上只有一种核心思想。其他形式都可以用它来证明,并解释为它的变体。这在知识上是经济的,避免了不同推理原则的泛滥。


如何选择证明方法

这自然引出了一个问题:我们该如何选择使用哪种方法?可以说,这取决于个人偏好。

事实上,当我在撰写证明时,我经常会尝试不同的版本。我会尝试用普通归纳法写一遍,再用良序原理写一遍,然后阅读两者,决定哪一个看起来更清晰明了,就选择哪一个。因此,并没有关于选择哪种方法的简单规则,但在某种意义上,这真的不重要,你只需选择一种即可。

当然,唯一的例外是在考试或类似场合,题目要求你使用其中一种特定的方法,以展示你对该方法的理解。那时,你就不能随意选择了。


教学策略:为何先讲良序原理

最后,我们讨论一个教学法上的问题:为什么在6.042这门课中,我们先讲授良序原理(事实上是在第二讲),直到现在第三周快结束时才讲到更为人熟悉、许多人认为更喜欢的归纳法原理?

答案是,这是一种教学策略。事实上,教材作者们对此意见并不统一。我的观点是,先讲良序原理更好。原因在于,根据与学生们的交流、调查以及考试成绩,我们的印象是,无论我们多么努力地解释和教授归纳法,只有大约20%的学生真正掌握了它。

他们报告说,担心“假设 P(n) 成立去证明 P(n+1)”在某种程度上是循环论证。可以明确观察到,大约20%的学生无法可靠地进行归纳法证明。这让另外80%觉得归纳法显而易见、能轻松掌握的学生感到困惑,也让我们教师感到困惑。我们无法弄清楚那20%的学生到底遇到了什么问题,并且我们已经尝试了多种不同的方式来教授归纳法。

另一方面,没有人难以理解良序原理,并且在使用它时,他们肯定不比使用普通归纳法或强归纳法时更困难。关于“它安全吗?我真的相信它吗?”这种概念性问题,在良序原理上根本不会出现。每个人都同意“一个非空的非负整数集合必然有一个最小元素”是显而易见的。

因此,我们选择一开始就讲授良序原理,因为解释它没有额外的认知负担,并且它能让我们从一开始就着手进行有趣的证明,而不是等待一段时间,或者花几节课的时间讲解归纳法,却让部分学生将其视为唯一(且难以掌握)的证明非负整数性质的方法。


总结

本节课中我们一起学*了普通归纳法、强归纳法与良序原理之间的等价关系。我们看到,强归纳法在逻辑上并未超越普通归纳法,它主要提供了更简洁的表述。而良序原理与归纳法则本质上是同一核心思想的不同表述形式,选择哪一种通常取决于证明的清晰度和个人偏好。理解它们的等价性,能帮助我们在面对问题时,灵活选用最合适的证明框架。

MIT 6.042J 计算机科学的数学基础:P24:L1.9.1- 状态机与不变量 🧮

在本节课中,我们将要学*状态机以及如何使用不变量来分析它们。状态机是描述逐步过程的有力模型,在计算机科学和数字电路设计中非常常见。我们将通过几个有趣的例子,学*如何形式化地定义状态机,并利用“保持不变量”的原理来证明状态机的一些重要性质。

什么是状态机? 🤖

上一节我们介绍了状态机的基本概念。状态机用于建模按步骤执行的过程。例如,计算过程通常被看作是一步接一步地执行指令,直到最终终止。同样,各种数字电路也会经历一系列状态,直到产生最终输出。

状态机的一般模型可能涉及输入和响应,但为了我们的目的,我们可以先看一个简单的例子。下面是一个计数到99的状态机:

状态用圆圈表示,命名为0到99,还有一个名为“溢出”的最终状态。双圈标记表示起始状态。箭头表示状态之间的转换。

以下是该状态机的完整数学描述:

  • 状态集合{0, 1, 2, ..., 99, 溢出}
  • 转换规则: 对于 i 在 0 到 98 之间,有 i -> i+199 -> 溢出溢出 -> 溢出

这个状态机一旦进入“溢出”状态就会永远停留,一个更有用的真实机器会有一个将“溢出”重置为0的转换,但这个例子已经说明了基本思想。

示例:《虎胆龙威》水壶问题 💧

现在,我们来看一个来自电影《虎胆龙威》的有趣例子。电影中,反派西蒙给出了一个挑战:有一个3加仑的水壶和一个5加仑的水壶,以及一个无限供水的水源。目标是通过倒水操作,在其中一个水壶中得到恰好4加仑的水。

我们需要将这个问题形式化为一个状态机。首先,我们需要决定状态是什么。一个明显的模型是用水壶中的水量来表示状态。设 B 为大壶(5加仑)中的水量,L 为小壶(3加仑)中的水量。B 的取值范围是0到5,L 的取值范围是0到3。为了精确控制,我们要求水量必须是整数。

接下来,我们定义可能的转换(操作)。起始状态是 (0, 0),即两个水壶都空。

以下是所有允许的安全操作(避免因随意倒水而无法追踪水量):

  • 灌满小壶: 如果 L < 3,则 (B, L) -> (B, 3)
  • 灌满大壶: 如果 B < 5,则 (B, L) -> (5, L)
  • 倒空小壶(B, L) -> (B, 0)
  • 倒空大壶(B, L) -> (0, L)
  • 将大壶倒入小壶
    • 如果 B + L <= 3(无溢出),则 (B, L) -> (0, B+L)
    • 否则(有溢出),则 (B, L) -> (B - (3-L), 3)。即,将小壶倒满,大壶剩余 B - (3-L) 加仑。
  • 将小壶倒入大壶
    • 如果 B + L <= 5(无溢出),则 (B, L) -> (B+L, 0)
    • 否则(有溢出),则 (B, L) -> (5, L - (5-B))。即,将大壶倒满,小壶剩余 L - (5-B) 加仑。

这就是《虎胆龙威》水壶问题的状态机形式化描述。

如何得到4加仑?

西蒙的挑战是得到恰好4加仑水。我们可以通过一系列状态转换来实现:

  1. 起始状态:(0, 0)
  2. 灌满大壶:(5, 0)
  3. 将大壶水倒入小壶:(2, 3)。(大壶剩2加仑,小壶满)
  4. 倒空小壶:(2, 0)
  5. 将大壶水倒入小壶:(0, 2)
  6. 灌满大壶:(5, 2)
  7. 将大壶水倒入小壶(直到小壶满):小壶已有2加仑,只能再倒入1加仑。操作后状态为 (5-1, 3) = (4, 3)

成功!我们在5加仑的大壶中得到了4加仑水。

保持不变量与弗洛伊德不变量原理 🔍

上一节我们解决了原始问题。现在,让我们提出一个新问题:如果把5加仑壶换成9加仑壶(即一个3加仑壶和一个9加仑壶),还能否得到4加仑水?

直觉上,你可能会发现,无论你怎么操作,每个水壶中的水量似乎总是3的倍数。这是一个保持不变量。我们可以这样表述:对于任何可达状态 (B, L),性质 P(B, L)3 整除 B,且 3 整除 L 始终成立。(符号 3 | B 表示“3整除B”)。

为什么这是一个保持不变量?我们需要检查所有转换规则。以“将大壶倒入小壶(有溢出)”这一复杂规则为例:
转换是: (B, L) -> (B - (3-L), 3)
假设在旧状态中,3 | B3 | L(即B和L都是3的倍数)。那么在新状态中:

  • 小壶水量为3,显然能被3整除。
  • 大壶水量为 B - (3 - L) = B + L - 3。由于B和L都是3的倍数,B+L也是3的倍数,B+L-3也是3的倍数。

检查所有其他转换规则,同样成立。如果旧状态满足性质P,那么经过任何转换得到的新状态也满足性质P。这就是保持不变量的定义。

由于起始状态 (0, 0) 满足P(0能被任何数整除),根据弗洛伊德不变量原理,所有从起始状态可达的状态都满足性质P。

弗洛伊德不变量原理指出:如果一个性质P是保持不变量(即从任意满足P的状态出发,经过一步转换到达的新状态也满足P),并且起始状态满足P,那么P在所有可达状态中都成立。这本质上是归纳法在状态机上的应用。

因此,在3加仑和9加仑水壶的问题中,所有可达状态的水量都是3的倍数。而目标水量4不是3的倍数,所以不可能达到。布鲁斯·威利斯这次恐怕在劫难逃了。

注意:严格来说,我们要区分“保持不变量”和“不变量”。一个在所有状态中都成立的性质叫“不变量”。我们通过找到一个“保持不变量”并证明起始状态满足它,来证明该性质是一个“不变量”。恒假的性质(如 1=0)是*凡的保持不变量,但不是我们通常关心的不变量。

更多示例:机器人移动与快速幂算法 ⚡️

为了巩固理解,我们再看两个使用不变量分析的例子。

示例1:对角线移动的机器人

假设一个机器人在整数网格上移动,其坐标为 (x, y)xy 都是非负整数。它每一步只能沿对角线移动:东北 (+1, +1)、东南 (+1, -1)、西北 (-1, +1)、西南 (-1, -1)

问题:从原点 (0, 0) 出发,能否到达点 (0, 1)

答案是否定的,原因在于一个保持不变量:坐标和 x + y 的奇偶性

  • 观察每一步移动:xy 同时变化 ±1。因此,x+y 的变化可能是 +2, 0, 或 -2。无论哪种情况,x+y 的奇偶性(是奇数还是偶数)都保持不变
  • 起始状态 (0, 0)0+0=0 是偶数。
  • 根据弗洛伊德原理,所有可达状态的 x+y 都是偶数。
  • 目标状态 (0, 1)0+1=1 是奇数。
  • 因此,(0, 1) 不可达。

这个奇偶性不变量将帮助我们分析更复杂的“15拼图”游戏。

示例2:快速幂算法

最后,我们看一个重要的算法示例——快速幂算法,并用不变量验证其正确性。目标是高效计算 a^b(a的b次方),其中a是实数,b是非负整数。

算法的状态机描述如下:

  • 状态: 一个三元组 (x, y, z),其中 x, y 是实数,z 是非负整数。
  • 起始状态(a, 1, b)x 存放底数a,y 作为累加器初始为1,z 存放指数b。
  • 转换规则
    1. 如果 z > 0z偶数(x, y, z) -> (x^2, y, z/2)
    2. 如果 z > 0z奇数(x, y, z) -> (x^2, x*y, (z-1)/2)
  • 终止状态: 当 z = 0 时,算法停止,此时 y 中存放的就是结果。

这个算法的关键在于一个保持不变量:在任何状态 (x, y, z) 下,恒有 y * (x^z) = a^b

验证(以z为奇数的转换为例):
假设旧状态 (x, y, z) 满足不变量:y * x^z = a^b
转换后新状态为 (x^2, x*y, (z-1)/2)
检查新状态是否满足不变量:
y * (新 x) ^ (新 z) = (x*y) * (x^2)^((z-1)/2)
= (x*y) * x^(z-1)
= y * x^z
= a^b
成立!对于z为偶数的转换,验证类似。

由于起始状态 (a, 1, b) 满足 1 * a^b = a^b,根据弗洛伊德原理,该不变量在所有可达状态成立。
当算法终止于 z=0 时,不变量变为:y * x^0 = y = a^b。因此,最终 y 中的值就是正确的 a^b

我们还需要证明算法总会终止。因为 z 是正整数,每次转换后 z 至少减半(z/2(z-1)/2),所以最多经过大约 log₂(b) 步,z 就会变为0,算法终止。

这个算法的设计者和不变量原理的阐述者之一,是计算机科学家罗伯特·弗洛伊德。他在程序正确性验证和编程语言领域做出了奠基性贡献,并获得了图灵奖。

总结 📝

本节课中,我们一起学*了:

  1. 状态机的基本概念:状态集合、转换规则和起始状态。
  2. 如何将实际问题(如《虎胆龙威》水壶问题)形式化为状态机。
  3. 保持不变量的概念:在状态转换下保持不变的性质。
  4. 弗洛伊德不变量原理:如果保持不变量在起始状态成立,那么它在所有可达状态都成立。这是证明状态机全局性质(如“某些状态不可达”或“算法结果正确”)的强大工具。
  5. 我们通过水壶问题机器人移动快速幂算法三个例子,实践了如何发现、验证并应用不变量进行分析。

掌握状态机和不变量,为你理解计算过程、验证算法正确性奠定了重要的数学基础。

计算机科学的数学基础:L1.9.3:派生变量 📊

在本节课中,我们将要学*一种在分析状态机时非常有用的技术——派生变量。我们将了解它的定义、不同类型以及如何利用它来证明算法的终止性。

概述

派生变量是分析状态机行为的一种强大工具。它本质上是一个从状态映射到某个值的函数。通过观察这些值的变化规律,我们可以推断出状态机的性质,例如它是否会终止。

什么是派生变量?

上一节我们介绍了状态机的基本概念,本节中我们来看看如何通过派生变量来简化分析。

派生变量仅仅是状态机状态的函数。它给每个状态分配一个特定的值,可以看作是一种映射关系。

公式派生变量 v = f(状态 s)

这个函数的值可以是多种类型。如果值恰好是非负整数,我们称之为非负整数值派生变量。但它也可以是实数值、复数值,甚至其他类型的值。它不一定是数字。

派生变量的例子

为了更好地理解,让我们看几个具体的例子。

以下是两个来自“网格机器人”状态机的派生变量示例:

  • 和值变量 (σ):状态由坐标 (x, y) 组成。我们可以定义一个派生变量 σ = x + y。这是一个非负整数值派生变量。
  • 奇偶变量 (π):基于和值 σ,我们可以定义另一个派生变量 π。如果 σ 是偶数,则 π = 0;如果 σ 是奇数,则 π = 1

需要强调的是,“派生”意味着这个变量是我们构造出来的,它并不是原始状态机规范或程序定义的一部分。在机器人例子中,原始状态是 (x, y),而 σπ 是我们为了分析而引入的辅助工具。

利用派生变量证明终止

在“快速幂”算法的状态机分析中,我们遇到了一个关键的派生变量 z

我们观察到 z 是一个严格递减的自然数值变量。具体来说,它的值是非负整数,并且在状态机的每一步转换中,它的值都严格变小(在快速幂中,它每一步至少减半)。

核心原理:根据良序原理(任何非负整数集合都有最小值),一个严格递减的非负整数值变量最终必然会达到一个最小值。一旦达到最小值,它就无法再减小,这意味着状态机无法再进行转换,从而算法必须终止

这为我们提供了一种证明程序终止的通用方法:找到一个值域为非负整数的严格递减派生变量。

更进一步,我们有时还能分析算法运行的时间界限。在快速幂例子中,因为 z 每一步至少减半,所以步数的上界是 O(log z),而不仅仅是 z

严格递减变量的定义:在状态机的每一步转换中,该变量的值都变小。

其他类型的派生变量

除了严格递减变量,还有其他有用的类型。

一个相关的概念是弱递减变量。这类变量不一定能直接证明终止,但对分析算法行为很有帮助。

弱递减变量是一个在每一步转换中,值保持不变或变小的变量。在微积分领域,这通常被称为“非递增”函数。

与递减变量相对的是弱递增变量(值保持不变或变大)和常数变量

如果一个变量既是弱递增又是弱递减,那么它就是一个常数变量。在之前的机器人例子中:

  • 和值变量 σ 既非严格递增也非严格递减。
  • 奇偶变量 π 则是一个常数变量。

概念的推广:良序集

非负整数变量的概念可以直接推广到更一般的良序集

良序集是指一个集合,其中不存在无限递减的序列(即你无法找到一个值 w0 > w1 > w2 > ... 永远持续下去)。非负整数集是最典型的良序集。

终止原则的推广:如果你能找到一个严格递减的派生变量,并且它的值总是来自一个良序集,那么这同样能保证状态机终止。原因同上:变量必须达到该良序集中的一个最小值。

总结

本节课中我们一起学*了派生变量这一核心分析工具。我们了解到:

  1. 派生变量是状态的一个函数,用于辅助分析。
  2. 通过构造一个值域为非负整数(或更一般的良序集)的严格递减派生变量,可以证明状态机(算法)的终止性
  3. 还存在弱递减弱递增常数变量,它们有助于我们理解状态机的行为模式。

掌握派生变量的使用,将为我们后续分析更复杂的算法和系统奠定坚实的基础。

计算机科学的数学基础:L1.10.1:递归数据 📚

在本节课中,我们将要学*递归数据。递归数据是计算机科学中定义复杂结构的一种核心方法。我们将通过数学视角来理解其工作原理,并通过几个具体的例子来掌握如何定义和使用递归数据类型。

概述

递归数据的基本思想是:定义一类对象,其定义依赖于同一类对象的更简单版本。更精确地说,我们从一个已知的、非递归的基础对象集合开始,然后通过一系列构造函数规则,利用已有的对象来构造新的、更复杂的对象。这个过程是累积的,而非循环的,因为我们总是从已有的东西中构建出新的东西。

递归数据的定义方法

定义一个递归数据类型通常包含以下三个部分:

  1. 基础情况:指定一些最简单的、直接属于该类型的对象。
  2. 构造函数规则:说明如何通过组合已有的对象来创建该类型的新对象。
  3. 极值子句:这是一个隐含的规则,它声明“只有通过上述两种方式(基础情况或应用构造函数规则)得到的对象才属于该类型”。这个子句通常被默认理解,很少明确写出。

上一节我们介绍了递归数据的基本概念,本节中我们来看看具体的例子。

示例一:偶数集合 E

我们首先定义一个整数子集的递归数据类型 E

  • 基础情况0 属于 E
  • 构造函数规则
    1. 如果 n 属于 En >= 0,那么 n + 2 也属于 E
    2. 如果 n 属于 En > 0,那么 -n 也属于 E

让我们看看如何构造 E 中的元素。从基础情况 0 开始,反复应用第一个构造函数规则,我们可以得到 0, 2, 4, 6, ...,即所有非负偶数。然后,对这些正数应用第二个构造函数规则(取负),我们可以得到 -2, -4, -6, ...。因此,E 包含了所有偶数。

根据极值子句,E只有通过上述方式构造出来的元素。所以我们可以得出结论:E 恰好是所有偶数的集合。

示例二:匹配括号字符串集合 M

现在,我们来看一个更有趣的例子:定义所有左右括号正确匹配的字符串集合 M。我们用 { ), ( }* 表示所有由左右括号组成的有限字符串的集合。

  • 基础情况:空字符串 ε 属于 M
  • 构造函数规则:如果字符串 st 都属于 M,那么由 (s)t 连接而成的新字符串 (s)t 也属于 M

让我们练*一下这个构造过程:

  1. 最初,我们只有 ε。令 s = ε, t = ε,应用构造函数得到 ()ε,即 ()
  2. 现在 M 中有 ε()。我们可以令 s = (), t = ε,得到 (())。或者令 s = ε, t = (),得到 ()()
  3. 继续这个过程,我们可以构造出 (()())((()))()()() 等所有匹配的括号字符串。

基于这个递归定义,我们可以证明一些性质。例如,我们可以证明:M 中没有任何字符串以右括号 ) 开头

  • 基础情况 ε 不以 ) 开头。
  • 构造函数规则生成的所有新字符串都以左括号 ( 开头。
  • 根据极值子句,M 中的元素只能通过上述方式获得。因此,M 中不可能存在以 ) 开头的字符串。

示例三:F18 函数类

最后,我们看一个关于函数的递归定义示例:F18 函数类,它涵盖了微积分入门课程中常见的单变量实函数。

  • 基础情况:以下函数属于 F18:
    • 恒等函数 f(x) = x
    • 任意常数函数 f(x) = c(c 为常数)
    • 正弦函数 f(x) = sin(x)
  • 构造函数规则:如果 fg 是 F18 中的函数,那么以下函数也属于 F18:
    • 加法:f + g
    • 乘法:f * g
    • 指数:2^f (即以 2 为底,f(x) 为指数的函数)
    • 求逆:f^{-1}(在逆函数有定义的情况下)
    • 复合:f ∘ g

让我们看看如何用这些规则推导出其他常见函数:

  • 负函数 f(x) = -x:常数函数 -1 乘以恒等函数 x 得到 -x
  • *方根函数 f(x) = √x:恒等函数 x 自乘得到 x^2,然后对其求逆得到 √x
  • 余弦函数 f(x) = cos(x):方法一,sin(x + π)sin(x + π) 的复合,而 (x + π)x 与常数 π 的和。方法二,利用恒等式 cos(x) = √(1 - sin^2(x)),通过常数函数、乘法、减法和*方根运算得到。
  • 自然对数函数 f(x) = ln(x):首先,常数 log_2(e) 乘以 x 得到 log_2(e) * x,然后应用指数构造函数得到 2^(log_2(e) * x) = e^x,最后对 e^x 求逆即得到 ln(x)

这个例子展示了递归定义的强大之处:从一个小的基础集合出发,通过有限的规则可以构造出一个非常丰富且复杂的函数家族。

总结

本节课中我们一起学*了递归数据。我们了解到,递归数据类型通过基础情况构造函数规则来定义,并隐含了极值子句。我们通过三个例子——偶数集合 E、匹配括号字符串集合 M 和 F18 函数类——具体实践了如何定义递归数据类型,并利用定义来推导其性质或构造复杂对象。递归是计算机科学中表示无限复杂结构(如链表、树、表达式)的基石,掌握其数学定义是理解这些结构的关键。

计算机科学的数学基础:P27:L1.10.4- 结构归纳法 🧱

在本节课中,我们将要学*一种重要的证明方法——结构归纳法。它专门用于证明递归定义的数据类型所具有的性质。我们将通过几个具体的例子,来理解其工作原理和应用方式。

结构归纳法的原理

上一节我们介绍了递归定义的数据类型。本节中我们来看看如何证明这类数据类型的性质。

每当定义一个递归数据类型时,其定义中隐含了一种证明方法,称为结构归纳法。结构归纳法的工作方式如下:如果你想证明某个递归定义的数据类型中的每一个元素都具有特定性质 P,那么你需要按以下步骤进行:

  1. 基础步骤:证明基础情形 R 中的每一个元素都具有性质 P
  2. 归纳步骤:对于每一个构造器 C,证明:如果你将构造器 C 应用于元素 X,那么只要 X 具有性质 P(你可以将此作为结构归纳假设 P(X)),那么 C(X) 也具有性质 **P`。

有些构造器接受多个参数,但以上模式说明了其通用思想。

简单示例:偶数集

让我们先看一个简单的例子。我们在之前的讲解中实际上已经见过这个方法,但没有特别强调它。当时我们论证了递归定义的集合 E 只包含偶数。

以下是集合 E 的定义:

  • 基础情形0 ∈ E
  • 构造情形:如果 n ∈ E,那么 n+2 ∈ E-n ∈ E

我们想通过归纳法证明 X 是偶数。我们需要检查:

  • 基础情形0 是偶数,成立。
  • 归纳步骤:假设归纳假设 n 是偶数成立,那么当我们应用构造器 n+2 时,结果显然是偶数;应用构造器 -n 时,结果也是偶数。

因此,结构归纳法告诉我们,集合 E 中的每一个字符串(数字)确实都是偶数。

匹配括号示例

现在让我们看一个更有趣的例子:匹配的左右括号集合 M。我想通过结构归纳法证明:M 中的每一个字符串都包含相同数量的左括号和右括号。

我可以重新表述这个命题:定义 EQ 为包含相同数量左右括号的字符串集合。那么我真正想说的是:MEQ 的一个子集。

以下是证明方法:

  • 定义我的归纳假设 P(s) 为:字符串 s 属于 EQ,即 s 具有相同数量的左括号和右括号。
  • 回忆 M 的定义:
    • 基础情形:空字符串 λ(没有括号)属于 M
    • 构造情形:如果 RT 属于 M,那么 [R]T 也属于 **M`。

以下是证明过程:

  1. 基础步骤:空字符串 λ 满足 P(s) 吗?是的,它有 0 个右括号和 0 个左括号,数量相等。因此我们确立了基础情形 P(λ) 为真。
  2. 归纳步骤:我们需要考虑构造情形。假设 RT 属于 M,并且归纳假设 P(R)P(T) 成立(即 RT 各自左右括号数量相等)。现在考虑通过构造器得到的字符串 s = [R]T
    • 字符串 s 中的右括号数量 = R 中的右括号数 + T 中的右括号数 + 1(因为构造器额外添加了一个 ])。
    • 字符串 s 中的左括号数量 = R 中的左括号数 + T 中的左括号数 + 1(因为构造器额外添加了一个 [)。
    • 根据归纳假设 P(R)R 中左右括号数相等;根据 P(T)T 中左右括号数也相等。
    • 因此,上面两个等式的右边是相等的,所以 s 中的右括号数量等于左括号数量。故 P(s) 为真。

构造情形得证。因此,我们可以通过结构归纳法得出结论:递归定义的匹配括号字符串集合 M 中的每一个字符串 s,确实都具有相同数量的左右括号。这意味着 MEQ 的子集,正如所声称的那样。

一个有趣的应用:F18函数

这些结构归纳证明相对简单。和常规归纳证明一样,当你找到正确的归纳假设时,证明往往会变得容易。我们将要研究一个与 F18函数 相关的有趣例子。

F18函数在微积分入门课程中被考虑的原因之一是:如果你观察所有这些函数(它们由常数函数、恒等函数 id(x)=x、正弦函数 sin(x) 通过加法、乘法、指数运算、复合等构造器组合而成),你会发现不需要添加“求导”作为一个构造器。因为可以通过结构归纳法证明:F18函数在求导运算下是封闭的。也就是说,任何一个F18函数的导数,仍然是一个F18函数。


本节课中我们一起学*了结构归纳法。它是一种强大的工具,用于证明递归定义集合或数据类型的性质。我们通过证明偶数集的性质、匹配括号字符串的*衡性,并提及了其在F18函数求导封闭性证明中的应用,掌握了其基础步骤和归纳步骤的核心思想。记住,关键在于:1)验证基础情形;2)在归纳假设下,证明每个构造器都能保持所需性质。

计算机科学的数学基础:P28:L1.10.7- 递归函数 📚

在本节课中,我们将学*如何在递归定义的数据类型上定义递归函数。我们将通过具体的例子,如匹配括号字符串的“深度”和指数运算,来理解其标准方法。同时,我们也会探讨一个关键问题:当数据类型定义不明确时,递归函数的定义可能会失败。


递归函数的定义方法 🔄

上一节我们介绍了递归数据类型,本节中我们来看看如何在其上定义函数。

在编程中,处理递归数据类型的标准做法是定义递归过程。具体方法如下:对于一个递归数据类型 R,我们定义一个函数 f。首先,为 R 的所有基本情况 b 直接定义 f(b) 的值。然后,对于每个构造函数 C(x),我们根据 xf(x) 来定义 f(C(x))

如果遵循这个结构,我们就得到了一个在递归定义数据集上的递归函数 f


示例一:匹配括号字符串的深度 🧱

为了使上述方法更清晰,我们来看一个在匹配括号字符串集合上定义递归函数的例子。

我们定义字符串的“深度”概念,它衡量括号嵌套的层数。

  • 基本情况:空字符串的深度为 0
  • 构造函数:如果 st 是匹配括号字符串,那么 (s)t 也是一个匹配括号字符串。其深度定义为 1 + max(深度(s), 深度(t))

用公式表示递归定义如下:

  • 深度(“”) = 0
  • 深度(“(s)t”) = 1 + max(深度(s), 深度(t))

示例二:更熟悉的递归定义——指数运算 ⚡

让我们看一个更熟悉的递归定义示例:计算 kn 次方(k 为整数或实数,n 为非负整数)。

  • 基本情况k^0 = 1
  • 递归步骤k^(n+1) = k * (k^n)

这个定义利用了非负整数可以递归定义的事实(0是整数;如果n是整数,则n+1也是整数),它本身就是结构归纳法的一个应用。


递归函数配方总结 📝

以下是定义递归函数的通用步骤:

  1. 确定递归数据类型 R
  2. 为所有基本情况 b 直接定义 f(b)
  3. 对于每个构造函数 C(x),用 xf(x) 来定义 f(C(x))

这样定义的函数 f 是良定义的。我们可以通过结构归纳法来证明关于这个函数的性质。


结构归纳法证明示例 ✅

现在,我们使用结构归纳法来证明关于括号字符串深度的一个性质。

命题:对于任何匹配括号字符串 r,其长度满足 |r| + 2 ≤ 2^(深度(r) + 1)

证明

  • 基本情况:当 r 是空字符串时,|r| = 0深度(r) = 0。左边 0 + 2 = 2,右边 2^(0+1) = 2。等式成立。
  • 归纳步骤:假设 r 由构造函数生成,即 r = (s)t,且归纳假设对 st 成立。我们需要证明命题对 r 成立。
    • 根据定义,|r| = |s| + |t| + 2(两个括号)。
    • 所以 |r| + 2 = (|s|+2) + (|t|+2)
    • 根据归纳假设,|s|+2 ≤ 2^(深度(s)+1)|t|+2 ≤ 2^(深度(t)+1)
    • 因为 深度(s)深度(t)≤ max(深度(s), 深度(t)),我们可以将指数替换为这个最大值,得到:
      |r|+2 ≤ 2 * 2^(max(深度(s), 深度(t)))
    • 根据深度定义,深度(r) = 1 + max(深度(s), 深度(t)),所以 max(深度(s), 深度(t)) = 深度(r) - 1
    • 代入上式:|r|+2 ≤ 2 * 2^(深度(r)-1) = 2^(深度(r)+1)

证明完成。


定义不明确导致的问题 ⚠️

上一节我们看到了成功的递归定义,本节中我们来看看一个因定义不明确而导致问题的例子。

假设我们递归定义“2的正幂”集合 P2

  • 基本情况2 ∈ P2
  • 构造函数:如果 x ∈ P2y ∈ P2,那么 x * y ∈ P2

现在,我们尝试在这个集合上定义一个“对数”函数 log_i

  • log_i(2) = 1
  • log_i(x * y) = log_i(x) + log_i(y) + 1 (注意,这里我们故意加了一个 +1,与常规对数不同,以制造问题)

让我们计算几个值:

  • log_i(4) = log_i(2*2) = log_i(2) + log_i(2) + 1 = 1 + 1 + 1 = 3
  • log_i(8) = log_i(2*4) = log_i(2) + log_i(4) + 1 = 1 + 3 + 1 = 5
  • log_i(16) 可以通过不同方式构造:
    • 构造方式一:16 = 8 * 2 -> log_i(16) = log_i(8) + log_i(2) + 1 = 5 + 1 + 1 = 7
    • 构造方式二:16 = 2 * 8 -> log_i(16) = log_i(2) + log_i(8) + 1 = 1 + 5 + 1 = 7。(巧合相同)
    • 构造方式三:16 = 4 * 4 -> log_i(16) = log_i(4) + log_i(4) + 1 = 3 + 3 + 1 = 7

在这个修改后的例子中,16 得到了相同的值 7。但如果我们把构造函数规则改为 log_i(x * y) = log_i(x) + log_i(y)(即常规对数),那么:

  • 16 = 8*2 -> log_i(16) = 5 + 1 = 6
  • 16 = 4*4 -> log_i(16) = 2 + 2 = 4
  • 16 = 2*8 -> log_i(16) = 1 + 3 = 4

此时,log_i(16) 得到了 64 两个不同的结果,这产生了矛盾。函数对于同一个输入必须输出唯一的值,因此这不是一个良定义的函数。


核心问题:定义的明确性 🎯

问题的根源在于数据类型 P2 的定义是不明确的。同一个元素(如 16)可以通过多种不同的方式构造出来。

当我们基于一个不明确的数据类型定义递归函数时,如果函数定义依赖于具体的构造路径,就可能给同一个元素赋予不同的值,从而导致矛盾。

因此,在定义递归函数时,我们必须确保:

  1. 递归数据类型本身的定义最好是明确的(如匹配括号字符串)。
  2. 如果数据类型不明确,则需要额外证明:无论使用哪种构造路径,函数定义都会产生相同的结果。例如,常规的以2为底的对数函数 log2(x*y) = log2(x) + log2(y)P2 上是良定义的,但这需要基于对数的性质来证明,而不能直接从递归定义中安全得出。

总结 🏁

本节课中我们一起学*了:

  1. 递归函数的定义方法:为基本情况直接赋值,为构造函数基于其组成部分的函数值进行定义。
  2. 应用示例:我们定义了匹配括号字符串的“深度”和指数运算 k^n
  3. 证明技术:我们使用结构归纳法证明了关于字符串深度的一个不等式。
  4. 关键注意事项:我们通过“2的正幂”集合上的伪对数函数例子,揭示了当递归数据类型定义不明确时,在其上定义递归函数可能导致矛盾。确保函数定义不依赖于具体的构造路径至关重要。

计算机科学的数学基础:P29:L1.11.1:集合的基数

在本节课中,我们将要学*集合的“基数”这一概念。基数用于描述集合的大小,特别是无限集的大小。我们将探讨为什么计算机科学需要关心无限集,并学*如何严谨地比较无限集的大小。

为什么关心无限集?

上一节我们引入了基数的概念,本节中我们来看看为什么计算机科学需要研究无限集。

虽然计算机内存中的每个数据结构都是有限的,我们计算的每个整数也是有限的,但抽象的“所有整数”的集合却是无限的。同样,所有可能被计算的矩阵的集合也是一个无限集。因此,我们经常理所当然地使用无限集并进行推理。

从教学角度看,引入无限集并严谨地推理,能迫使我们超越直觉,严格遵循数学规则。因为从有限集继承的一些性质在无限集中可能不再成立,我们必须仔细思考其背后的规则和性质。

最后,比较无限集大小的推理在计算机科学中具有深远意义,因为它引出了计算的理论极限,以及计算机无法解决的特定问题实例,我们将在后续视频中讨论。

康托尔的基数思想

现在,让我们回到基数的主题。19世纪末,数学家康托尔在研究级数时,为了表达其级数并非在“非常多”的无限点发散,发展出了比较无限集大小的思想。

根据映射引理,对于有限集A和B,当且仅当存在一个从A到B的满射函数时,A的大小大于或等于B的大小。康托尔的想法是:既然这对有限集成立,为何不将其作为定义,用于说明无限集A至少和B一样大呢?

因此,我们将 A surge B(存在从A到B的满射)理解为“A至少和B一样大”。对于有限集,这确实等价于A的元素数量大于等于B。

需要说明的是,谈论无限集的“大小”或“基数”本身是一个抽象且技术性的概念,实际用处不大。因此,我们不会直接讨论某个无限集的基数,而是会比较它们。我们将建立一个基础理论,来讨论一个集合的基数是否大于等于另一个集合的基数。

类似地,A bij B(存在从A到B的双射)将被理解为“A和B大小相同”。对于有限集,这确实意味着它们元素数量相同。对于无限集,我们采用双射关系来定义“大小相同”,即存在一个完美的、一一对应的映射。

一个双射的例子:幂集与无限比特串

以下是双射关系应用的一个例子:非负整数集N的幂集。

设N为非负整数集 {0, 1, 2, ...},其幂集是N的所有子集。我们可以发现,N的子集与无限比特串(由0和1组成的无限序列)之间存在一个明显的双射。

具体方法如下:对于N的任意一个子集(可能是无限子集),我们用一个无限比特串来表示它。如果某个整数n在子集中,则序列的第n位为1;如果不在,则为0。

这种逻辑与我们之前建立的非负整数有限子集与有限比特串之间的双射完全相同,只是现在将其扩展到了任意子集。因此,这定义了一个双射:每个整数子集对应一个唯一的无限比特串,反之亦然。

这里,符号 {0, 1}^ω 表示向右无限的比特串(有起点),以区别于 {0, 1}^*,后者表示所有有限比特串的集合。

基数关系的性质

上一节我们看到了如何用双射定义“大小相同”,本节我们来探讨基数关系的一些基本性质。如果“surge”和“bij”关系真的像大小比较一样运作,它们应该满足一些性质。

传递性

对于有限集,如果A的大小等于B,且B的大小等于C,那么A的大小等于C。这对无限集是否成立?即,如果 A bij BB bij C,是否意味着 A bij C

答案是肯定的。证明如下:由 A bij B 可知存在双射函数 g: A -> B。由 B bij C 可知存在双射函数 f: B -> C。我们需要从A到C找到一个双射。这很简单,只需将 gf 复合,即定义函数 h = f ∘ g。容易验证,如果 gf 都是双射,那么它们的复合 h 也是双射。这就找到了所需的从A到C的双射。

类似的性质也适用于“至少一样大”的关系(即surge)。对于有限集,如果A的大小 ≥ B,且B的大小 ≥ C,那么A的大小 ≥ C。同样的复合论证对满射也有效,因为满射函数的复合仍然是满射函数。因此,如果 A surge BB surge C,则 A surge C

施罗德-伯恩斯坦定理

让我们看另一个熟悉的性质:如果A的大小 ≥ B,且B的大小 ≥ A,那么A和B大小相同。这对有限集显然成立,但对无限集呢?

我们说的是:如果存在从A到B的满射函数,并且存在从B到A的满射函数,那么A和B之间存在一个双射。问题在于,这个从A到B的满射可能不是双射,从B到A的满射也可能不是双射。那么双射从哪里来?我们必须构造它。

这个性质是成立的,它被称为施罗德-伯恩斯坦定理。其技巧基本上是:利用给定的从A到B和从B到A的满射(或单射),以一种巧妙的方式组合它们的一部分,从而构造出所需的双射。这个证明需要一些巧思,包含在教材的*题中。因此,这是一个对surge和bij都成立的性质,但并不显而易见。

无限集的特有性质:大小加一等于大小

现在,让我们看一个不熟悉的大小性质,一个在有限集中不成立、因此我们必须谨慎对待的性质:对于无限集,大小加一等于大小

这是什么意思?让我们用一个例子来说明。事实上,你可以说无限集的一个定义就是其大小加一后仍等于自身大小。

看一个简单的例子:在下图底部,我们有非负整数集 N = {0, 1, 2, ...}。在顶部,我们有正整数集 Z+ = {1, 2, 3, ...}。正整数集加上元素0就得到了非负整数集,这就是“加一”的含义。一个无限集添加一个元素后,得到了另一个无限集,但它们大小相同。为了证明它们大小相同,我需要展示它们之间的一个双射。

这个双射是:将0映射到1,1映射到2,2映射到3,依此类推。这被称为“加一”函数 f(n) = n + 1,它将非负整数映射到正整数,并且是一个完美的双射。因此,在正整数集中添加一个元素0,并没有得到一个更大的集合,而是得到了一个大小相同的集合。

这个论证可以推广到任何无限集:如果你向一个无限集添加一个额外元素,你仍然可以在原集合和添加元素后的新集合之间找到一个双射。

另一个例子:整数集与非负整数集

再来看另一个例子:我可以枚举出所有整数(正、负和零):0, 1, -1, 2, -2, ... 这给出了整数集 Z。而在另一边,我可以列出非负整数:0, 1, 2, 3, ... 我在顶部有序列出整数的方式,隐式地定义了一个双射:我将0映射到序列的第一个元素(0),1映射到第二个元素(1),2映射到第三个元素(-1),3映射到第四个元素(2),4映射到第五个元素(-2),依此类推。

这样,我实际上定义了非负整数集与所有整数集之间的一个双射。换句话说,你取整数的一半(非负整数),它仍然与所有整数大小相同。在 NZ 之间存在一个双射。

如果你想写出一个公式来确定数字n映射到哪个整数(正或负),这涉及将n除以2并取整,但这不是关键。一旦我找到一种合理的方式将所有整数排成一行,我就可以将它们与非负整数对齐,而这种排列方式本身就定义了映射。

总结

本节课中,我们一起学*了集合基数的核心概念,特别是针对无限集。我们了解到:

  • 基数是比较集合大小的方式,对于无限集,我们通过满射定义“至少一样大”,通过双射定义“大小相同”。
  • 计算机科学关心无限集,因为它是许多抽象的基础,并且研究它能锻炼严谨的数学思维。
  • 基数关系满足传递性等性质,但像“大小加一等于大小”这样的性质是无限集特有的,与有限集直觉不同。
  • 我们通过具体的双射例子(如非负整数与正整数、非负整数与所有整数)加深了对这些抽象概念的理解。

理解这些内容是后续学*可计算性理论和计算极限的重要基础。

计算机科学的数学基础:L1.11.3:可数集合 📊

在本节课中,我们将学*可数集合的概念。可数集合是最常见的一类无限集合,理解它对于后续学*计算机科学中的数学基础至关重要。我们将通过定义、例子和引理来掌握如何判断一个集合是否可数。

可数集合的定义

上一节我们介绍了无限集合的基本概念,本节中我们来看看什么是可数集合。

一个集合被称为可数的,如果它的元素可以被“列出”。更正式地说,集合A是可数的,当且仅当在A与非负整数集合之间存在一个双射(即一一对应关系)。这意味着我们可以将A中的每个元素与一个唯一的非负整数(0, 1, 2, …)配对。

公式A 是可数的 ⇔ 存在双射 f: ℕ → A,其中 表示非负整数集合。

这个定义包含两种情况:

  1. 可数无限集合:集合A是无限的,并且存在这样的双射。
  2. 有限集合:有限集合也被认为是可数的。

可数集合的例子

以下是几个关键的可数集合例子,它们展示了如何构造与非负整数之间的双射。

  • 正整数集合:我们可以将正整数 n 映射到非负整数 n-1
  • 所有整数集合:我们可以按 0, 1, -1, 2, -2, 3, -3, … 的顺序列出所有整数。
  • 有限二进制字符串集合:所有由0和1组成的有限长度字符串(记作 {0,1}*)是可数的。我们可以按长度递增的顺序列出它们:
    • 空字符串
    • 所有长度为1的字符串:0, 1
    • 所有长度为2的字符串:00, 01, 10, 11
    • 以此类推。
  • 非负整数对集合:所有形如 (m, n) 的序对(其中 mn 是非负整数)是可数的。我们可以按照两数之和 m+n 递增的顺序列出它们,在每一“和”的块内按特定规则(例如按 m 递增)排序:
    • (0,0)
    • (0,1), (1,0)
    • (0,2), (1,1), (2,0)
    • 以此类推。

一个有用的引理

直接构造双射有时比较困难。下面这个引理提供了证明可数性的另一种更简便的方法。

引理:一个集合 A 是可数的,当且仅当存在一个从非负整数集合到 A满射

公式A 是可数的 ⇔ 存在满射 g: ℕ → A

这个引理非常有用,因为描述一个满射(允许“覆盖”集合A中所有元素,但允许重复)通常比描述一个双射(要求一一对应且无重复)更容易。

证明思路

  • 如果 A 是有限的,显然可以构造满射(例如,将多余的非负整数都映射到A的最后一个元素)。
  • 如果 A 是无限的,并且我们有一个满射 g: ℕ → A,它定义了一个允许重复的列表。要得到双射,我们只需从左到右遍历这个列表,过滤掉每个元素的重复出现,只保留其第一次出现的位置。由于A是无限的,这个过程将产生一个没有重复的无限列表,即一个双射。

引理的应用:有理数是可数的

现在,让我们运用这个引理来证明一个重要的结论:所有有理数的集合是可数的。直观上,有理数在数轴上非常“稠密”,似乎很难列出,但通过将其与已知的可数集合关联,我们可以轻松证明。

我们知道非负整数对 (m, n) 的集合是可数的。现在,我们构造一个从该集合到非负有理数的满射:

代码/映射描述f(m, n) = m / n (当 n ≠ 0);当 n = 0 时,定义 f(m, 0) 为某个固定的有理数(例如 1/2)。

这个映射是满射的,因为任何非负有理数都可以表示为两个非负整数的商 m/n(尽管表示方式可能不唯一,例如 1/22/4 都映射到同一个有理数,这正好满足了满射允许“重复”覆盖的要求)。

因此,根据我们的引理,非负有理数是可数的。通过类似的方法(例如将负有理数与负整数对关联),可以证明所有有理数的集合都是可数的。

不可数集合的预告

与有理数形成鲜明对比的是,实数集合是不可数的。同样,所有无限二进制序列的集合(例如代表 [0,1) 区间内实数的二进制展开)也是不可数的。事实上,可以证明无限二进制序列的集合与非负整数集的幂集(即所有子集的集合)之间存在双射,而这两个都是不可数集合的经典例子。我们将在后续课程中深入探讨。

总结

本节课中我们一起学*了:

  1. 可数集合的定义:存在与非负整数之间的双射。
  2. 几个基本的可数集合例子:整数、有限二进制字符串、非负整数对。
  3. 一个关键的引理:集合可数等价于存在从非负整数到该集合的满射。这为证明可数性提供了更便捷的工具。
  4. 应用该引理证明了有理数集合是可数的,这是一个重要且可能反直觉的结论。
  5. 了解到实数集无限二进制序列集不可数的,为后续学*奠定了基础。

掌握可数与不可数的概念,是理解计算理论中问题规模、算法复杂度以及可计算性概念的重要基石。

计算机科学的数学基础:L1.11.4:康托尔定理 🧮

在本节课中,我们将要学*不可数集的概念,并深入探讨康托尔定理。康托尔定理是集合论中的一个核心结论,它表明对于任何集合,其幂集(即所有子集的集合)的“大小”总是严格大于原集合的“大小”。我们将通过著名的对角线论证来证明这一点,并理解其深远意义。

不可数集与对角线论证

上一节我们介绍了可数集的概念。本节中我们来看看如何证明一个集合是不可数的。康托尔通过一个巧妙的方法——对角线论证——给出了明确的答案。

康托尔定理的核心思想是:对于任何给定的无穷大,都不存在“最大的”无穷大。你总能用一种简单的方法找到一个更大的无穷大。

让我们从最简单的形式开始,即如何使用对角线论证来证明一个集合是不可数的。回忆一下,一个集合是可数的,如果它的元素可以被列成一个序列(允许重复)。换句话说,集合A是可数的,如果存在一个序列 a0, a1, a2, ...,使得A中的每个元素都在该序列的某个位置出现。

例如,所有有限长度的二进制字符串(如“0”,“1”,“01”,“110”等)的集合是可数的。然而,如果我们考虑所有无限长的二进制序列(例如 01101001...,向右无限延伸),情况就不同了。我们将证明这是一个不可数集的例子。

对角线论证详解

我们如何用对角线论证来证明无限二进制序列的集合 {0, 1}^ω 是不可数的呢?思路如下:

  1. 假设可列:首先,为了推导矛盾,我们假设所有无限二进制序列是可列的。这意味着我们可以把它们全部列出来,形成一个无限长的列表:

    • S0 = (s00, s01, s02, ...)
    • S1 = (s10, s11, s12, ...)
    • S2 = (s20, s21, s22, ...)
    • ...
      这里,sij 表示第 i 个序列的第 j 位(0或1)。我们可以把这个列表想象成一个行和列都无限延伸的矩阵。
  2. 构造“对角线”序列:现在,我们沿着这个矩阵的“主对角线”构造一个新的二进制序列 DD 的第 idi 定义为与第 i 个序列 Si 的第 isii 相反

    • 如果 s00 = 0,则令 d0 = 1
    • 如果 s11 = 1,则令 d1 = 0
    • 如果 s22 = 0,则令 d2 = 1
    • ...
      用公式表示就是:di = 1 - siidi = NOT(sii)
  3. 证明矛盾:我们构造出的序列 D 不可能出现在我们假设的那个完整列表中。为什么呢?对于列表中的任何一个序列 SkD 在第 k 位上都与 Sk 不同(因为 dk ≠ skk)。因此,D 与列表中的每一个序列都至少有一位不同,所以它不在列表中。

  4. 得出结论:这就产生了矛盾。我们假设可以列出所有无限二进制序列,但却构造出了一个不在列表中的序列。因此,最初的假设是错误的。不存在从非负整数集 N 到无限二进制序列集 {0, 1}^ω 的满射。根据定义,这意味着 {0, 1}^ω 是不可数的。

这个论证之所以被称为“对角线”论证,是因为我们沿着假设列表形成的矩阵的对角线来构造反例。

严格“小于”关系的定义

在比较无限集的大小时,我们使用满射、单射和双射的语言。上一节我们利用对角线论证证明了 N{0, 1}^ω 的大小关系。本节我们来正式定义一个集合“严格小于”另一个集合的含义。

直观上,如果存在从集合 A 到集合 B 的满射,我们解读为 A 的“大小”大于或等于 B 的“大小”,记作 |A| ≥ |B|

基于此,我们可以定义“严格小于”:

我们说集合 A 严格小于 集合 B,记作 |A| < |B|,当且仅当不存在AB 的满射。

根据这个定义,我们刚才证明的正是:非负整数集 N 严格小于无限二进制序列集 {0, 1}^ω。因为不存在从 N{0, 1}^ω 的满射。

康托尔定理的一般形式

对角线论证的威力远不止于证明特定集合的不可数性。康托尔将其推广到了一个极其一般且优美的定理。

康托尔定理指出:对于任意集合 A(无论有限还是无限),其幂集 P(A)(即 A 的所有子集构成的集合)都严格大于 A 本身。用符号表示就是:|A| < |P(A)|

对于有限集,这很容易理解:如果 An 个元素,那么 P(A)2^n 个元素,并且对于所有 n ≥ 0,都有 n < 2^n。康托尔定理的非凡之处在于,它同样适用于无限集。

定理的证明(再次使用对角线论证)

证明的思路与之前证明 {0, 1}^ω 不可数时类似。

  1. 假设存在满射:为了推导矛盾,假设存在一个从集合 A 到其幂集 P(A) 的满射 f。这意味着对于 A 中的每个元素 af(a)A 的一个子集,并且 P(A) 中的每一个子集都是某个 a 的像。

  1. 构造“对角线”集:现在,我们利用函数 f 来构造一个新的集合 D,它是 A 的一个子集,定义如下:

    D = { a ∈ A | a ∉ f(a) }
    也就是说,D 包含所有那些“不属于其自身像”的 A 的元素。

  1. 证明矛盾:集合 D 显然是 A 的一个子集,因此 D ∈ P(A)。由于我们假设 f 是满射,那么必然存在某个 d ∈ A,使得 f(d) = D
    现在问一个问题:d 本身是否属于 D

    • 如果 d ∈ D,那么根据 D 的定义,必须有 d ∉ f(d)。但 f(d) = D,所以这意味着 d ∉ D。矛盾。
    • 如果 d ∉ D,即 d ∉ f(d)。那么根据 D 的定义,d 应该满足成为 D 成员的条件,即 d ∈ D。又产生矛盾。
  2. 得出结论:无论如何都导致矛盾。因此,最初的假设是错误的。不存在从集合 A 到其幂集 P(A) 的满射。根据“严格小于”的定义,这意味着 |A| < |P(A)|

这个证明的精妙之处在于,构造对角线集 D 的过程,本质上等价于在二进制序列情况下将对角线上的每一位取反。在这里,“对角线”体现在我们考虑每个元素 a 与其像 f(a) 的关系 a ∈? f(a) 上。

推论与应用

康托尔定理有许多重要的推论,帮助我们理解不同集合的“大小”。

推论1:自然数集的幂集是不可数的。
A = N(自然数集)。根据康托尔定理,|N| < |P(N)|。由于 N 是可数的,这意味着 P(N) 是不可数的。我们之前通过二进制序列间接证明了这一点,因为存在 {0, 1}^ωP(N) 之间的双射。

推论2:实数集是不可数的。
我们可以构造一个从实数集 R 到无限二进制序列集 {0, 1}^ω 的满射(例如,通过实数的二进制表示,并小心处理表示不唯一的情况)。既然 {0, 1}^ω 是不可数的(由康托尔定理或其特例证明),并且存在从 R 到它的满射,那么根据“若有从 C 到不可数集 A 的满射,则 C 也不可数”的原理,可以推出实数集 R 也是不可数的。这为“有理数可数而实数不可数”这一事实提供了另一个证明角度。

总结

本节课中我们一起学*了:

  1. 不可数集的概念,以及如何使用对角线论证来证明一个集合(如无限二进制序列集)是不可数的。
  2. 集合间“严格小于”(|A| < |B|)的正式定义:即不存在从 AB 的满射。
  3. 康托尔定理的核心内容:对于任何集合 A,其幂集 P(A) 总是严格大于 A 本身(|A| < |P(A)|)。我们通过一个巧妙的对角线论证一般化形式证明了这一定理。
  4. 康托尔定理的重要推论,包括自然数幂集的不可数性,以及实数集的不可数性。

康托尔定理深刻地揭示了无穷的层次性:不存在最大的无穷集合。从一个无穷集出发,总可以取其幂集来得到一个“更大”的无穷集,这个过程可以无限进行下去,从而产生一个无穷大的阶梯。这是现代集合论的基础之一。

计算机科学的数学基础:P32:L1.11.7- 停机问题 🛑

在本节课中,我们将要学*对角线论证的一个核心应用:停机问题。我们将看到如何利用对角线论证来证明存在不可计算的集合,并具体探讨一个著名的不可判定问题——停机问题。通过本课,你将理解为什么某些看似简单的问题,计算机却无法解决。


概述:对角线论证与不可计算性

上一节我们介绍了对角线论证,它是一种处理无限集合的优雅方法。本节中我们来看看对角线论证在计算理论中的一个基本应用:证明存在不可计算的集合

我们已经知道,存在不可数多个无限的二进制字符串。这是因为无限的二进制字符串与自然数的子集(即自然数的幂集)之间存在一个简单的双射关系。

现在,让我们考虑其中那些被称为可计算字符串的字符串。所谓可计算字符串,是指存在一个简单的程序,能够计算出该字符串的任意第n位数字。用公式表示,即存在一个程序 P,对于字符串 s,当输入 n 时,P(n) 能返回 s 的第 n 位。

定义:字符串 s 是可计算的,当且仅当存在一个程序 P,使得对于任意 n,P(n) = s[n]。

由于程序本身可以用有限的ASCII字符串来描述,而所有有限ASCII字符串的集合是可数的(你可以按长度顺序列出它们,就像对二进制字符串所做的那样),因此,只有可数多个可能的程序。

由此我们可以立即得出结论:只有可数多个可计算的无限二进制序列。然而,我们已经知道无限的二进制序列集合是不可数的。因此,必然存在不可计算的无限二进制序列。事实上,绝大多数无限二进制序列都是不可计算的。

这是一个抽象的存在性结果。但一个合理的问题是:它们具体是什么样子的?我们能否找到一个具体的、有意义的计算问题,并证明它是不可计算的?


停机问题:一个具体的不可判定问题

接下来,我们将探讨一个特定的、明智的具体计算问题:停机问题

停机问题是指:给定一个程序(描述)和一个输入参数,判断该程序在给定输入上运行是否会成功停止(即返回值),还是会永远运行下去、返回错误或发生其他“不好”的事情。

我们说一个程序在输入上“停机”,当且仅当它成功返回一个值。

停机问题是不可判定的。这意味着,不存在一个通用的程序 H,当输入任意程序 P 的描述及其输入 x 时,H(P, x) 总能正确判断 P(x) 是否会停机。

为了更详细地分析,让我们将讨论范围限定在字符串过程上。我们考虑那些接受字符串作为参数的程序,并且程序本身也用ASCII字符串描述。

我们定义一个字符串属性 halts
一个字符串 s 具有 halts 属性,当且仅当将 s 解释为一个过程描述 P,并将 P 应用于它自身(即输入 s)时,P(s) 成功停止。

定义: halts(s) 为真 ⇔ 程序P_s(由s描述)在输入s上成功停止。

这体现了“对角线”的思想:我们将描述程序 P_s 的字符串 s,作为输入喂给 P_s 本身。


证明:不存在停机判定器

现在,我们通过反证法来证明不存在能判定 halts 属性的程序。

  1. 假设存在判定器:为了引出矛盾,我们假设存在一个程序 Q,它是一个完美的停机判定器。

    • 对于任意输入字符串 sQ(s) 返回 "yes",当且仅当 halts(s) 为真(即 s 描述的进程在输入 s 上停止)。
    • Q(s) 返回 "no",当且仅当 halts(s) 为假(即永远运行、出错等)。
  2. 构造“互补”程序:我们利用 Q 来构造一个新程序 Q‘Q‘ 的行为与 Q 在输出上“互补”:

    • 如果 Q(s) 返回 "yes",则 Q‘(s) 不返回任何值(即它不停止,例如进入无限循环)。
    • 如果 Q(s) 返回 "no",则 Q‘(s) 返回 "yes"
    定义 Q‘(s):
        if Q(s) == "yes":
            while True: pass  # 进入无限循环,永不停止
        else if Q(s) == "no":
            return "yes"
    

  1. 考虑 Q‘ 自身的描述:令 t 为描述程序 Q‘ 的ASCII字符串。现在,我们问:halts(t) 是真还是假?即 Q‘(t) 会停止吗?

  1. 推导矛盾

    • 根据 halts 的定义:halts(t) 为真 ⇔ Q‘(t) 停止。
    • 根据 Q‘ 的定义:
      • 如果 Q(t) 返回 "yes"(即 halts(t) 为真),那么 Q‘(t) 会进入无限循环,永不停止
      • 如果 Q(t) 返回 "no"(即 halts(t) 为假),那么 Q‘(t) 会返回 "yes"成功停止
    • 将两者结合:
      • halts(t) 为真 ⇒ Q(t) 返回 "yes"Q‘(t) 永不停止 ⇒ halts(t) 为假。矛盾
      • halts(t) 为假 ⇒ Q(t) 返回 "no"Q‘(t) 成功停止 ⇒ halts(t) 为真。矛盾

    我们得到了一个逻辑矛盾:halts(t) 为真当且仅当它为假。这不可能。

  2. 结论:因此,我们最初的假设——存在一个完美的停机判定器 Q——是错误的。停机问题是不可判定的


推论:不存在完美的类型检查器

上述关于停机问题的不可判定性结论,可以推导出许多其他问题的不可判定性。以下是一个贴*实际兴趣的例子:类型检查

一个完美的类型检查器 C,输入一个程序(字符串)s,应能判断运行 s 是否会导致运行时类型错误。

  • C(s) 返回 "yes",表示 s 会导致类型错误。
  • C(s) 返回 "no",表示 s 是类型安全的。

我们将证明:如果存在这样的完美类型检查器 C,我们就可以用它来解决停机问题。既然停机问题不可解,那么完美的类型检查器也不可能存在。

证明思路如下

  1. 假设存在完美类型检查器 C

  2. 我们利用 C 来构造一个停机判定器 H,其工作流程如下:

    • 输入:一个程序描述字符串 s
    • H 首先构造一个新程序 s‘s‘ 是一个“解释器”,它会逐步模拟原程序 s 在输入 s 自身时的行为,但进行以下修改:
      • 如果模拟发现 s 即将导致运行时类型错误,s‘ 会跳过导致错误的指令,继续模拟。
      • 如果模拟发现 s 成功停止并返回值,s‘故意执行一个导致类型错误的操作。
    • 然后,Hs‘ 交给类型检查器 C 进行检查,并输出 C(s‘) 的结果。
  3. 分析 s‘ 的行为与 s 是否停机的关系

    • 如果 s 在自身输入上停机(成功返回),根据构造,s‘ 会故意引发类型错误。因此 C(s‘) 会返回 "yes"。根据 H 的定义,H(s) 也返回 "yes"
    • 如果 s 在自身输入上不停机(永远循环或出错),那么 s‘ 在模拟时永远不会遇到 s 成功返回的时刻,也就不会故意引发类型错误。同时,s‘ 会跳过所有 s 可能引发的真实类型错误。因此 s‘ 本身可能永远运行,但不会产生类型错误。所以 C(s‘) 会返回 "no"。根据 H 的定义,H(s) 也返回 "no"

  1. 由此可见,我们构造的 H 完美地解决了停机问题。但这与“停机问题不可判定”相矛盾。
  2. 因此,最初的假设(存在完美类型检查器 C)是错误的。不存在完美的类型检查器

这个论证不仅适用于类型检查,它表明:对于程序行为可能展现的几乎所有非*凡属性(如“是否会产生某个特定输出”、“是否会在10步内停止”等),都不存在能完美判定该属性的通用检查器。这就是理论计算机科学家对对角线论证如此尊重和感兴趣的原因,它揭示了计算的固有极限。


总结

本节课中我们一起学*了:

  1. 利用对角线论证,我们知道了存在不可计算的无限序列,因为可计算的序列只是可数集,而无限二进制序列是不可数集。
  2. 我们深入探讨了停机问题,这是一个具体且重要的不可判定问题。通过巧妙的“自指”构造(让程序分析其自身),我们证明了不存在一个通用算法能判定任意程序是否会停机。
  3. 作为推论,我们看到了如何将停机问题的不可判定性,归约到其他实际问题(如完美的类型检查)上,从而证明这些问题同样不可判定。

对角线论证因此成为计算理论中一个强有力的工具,它具体化并证明了一整套逻辑上不可避免的计算限制。

计算机科学的数学基础:P33:L1.11.9 - 罗素悖论 🧩

在本节课中,我们将探讨集合论的一个基础概念,并了解一个著名的逻辑悖论——罗素悖论。我们将看到,之前讨论过的对角线论证法在集合论的发展中扮演了关键角色。同时,我们也会对比计算机科学中常见的自引用操作,理解为何数学在处理此类问题时需要格外谨慎。

自引用与计算机科学

上一节我们介绍了对角线论证法,本节中我们来看看自引用这个概念。在计算机科学中,自引用是常见且被允许的操作,但在数学基础中,它却可能导致严重问题。

以下是计算机科学中自引用的两个例子:

  1. 自引用数据结构:在Scheme/Lisp等语言中,可以创建包含自身作为元素的列表。通过操作指针,可以使一个列表的某个元素指向列表自身,形成一个有限的循环结构,却能表示无限的嵌套数据。

    (define L (list 0 1 2))
    (set-car! (cdr L) L) ; 将L的第二个元素设置为L本身
    

    执行后,L 变成了一个形如 (0, L, 2) 的列表,其中 L 自身是其成员。

  2. 函数的自应用:在高阶函数编程中,函数可以接受自身或其他函数作为参数,并应用于自身。

    (define (compose f g)
      (lambda (x) (f (g x))))
    
    (define (cop2 f) (compose f f)) ; 定义函数f与自身的复合
    
    ; 应用示例:将*方函数与自身复合,得到四次方函数
    ((cop2 square) 3) ; 结果为 81 (即 3^4)
    

    我们甚至可以定义更复杂的自应用,例如 (cop2 cop2),它表示将一个函数与自身复合四次。

这些操作在类型灵活或支持递归的编程语言中是完全合法且有用的。

罗素悖论

然而,数学家对自引用持谨慎态度,这很大程度上源于伯特兰·罗素提出的著名悖论。罗素悖论动摇了19世纪末数学家试图为数学建立严谨集合论基础的尝试。

罗素构造了一个集合 W,其定义如下:

W =

用文字描述:W 是所有“不属于自身”的集合构成的集合。

现在,让我们思考 W 本身是否属于 W。根据定义:

  • 如果 W ∈ W,那么 W 必须满足定义条件,即 W ∉ W
  • 如果 W ∉ W,那么 W 恰好满足了“不属于自身”的条件,因此 W ∈ W

我们得到了一个逻辑矛盾:W ∈ W 当且仅当 W ∉ W。这个悖论表明,将 W 视为一个普通的集合会导致不一致性。

悖论的解决与影响

罗素悖论对当时正在构建集合论体系的数学家戈特洛布·弗雷格造成了沉重打击。弗雷格的工作几乎因此被全盘否定。

解决这个悖论的关键在于认识到:并非所有明确定义的数学对象都能构成一个“集合”。W 的定义虽然是清晰的,但其规模“太大”或性质太特殊,以至于不能被视为一个集合(在现代集合论中,这类对象被称为“真类”)。

因此,为了避免悖论,现代公理化集合论(如ZF系统)引入了严格的公理来限定哪些对象可以合法地称为集合,特别是限制“过大”集合的形成。这回答了“何时一个明确定义的数学对象是一个集合”这个根本的哲学问题。

总结

本节课中我们一起学*了自引用概念以及著名的罗素悖论。我们了解到:

  1. 在计算机科学中,数据结构和函数的自引用是有效且强大的工具。
  2. 在数学基础的集合论中,无限制的自引用(如“所有不属于自身的集合的集合”)会导致逻辑悖论。
  3. 罗素悖论的解决促使数学家建立了更严谨的公理化集合论,通过规则区分“集合”和“真类”,从而为数学奠定了更稳固的基础。

这个历程展示了在构建严谨的逻辑系统时,明确边界和规则的重要性。

MIT 6.042J:计算机科学的数学基础:P34:L1.11.11- 集合论公理 🧮

在本节课中,我们将要学*Zermelo-Fraenkel集合论公理系统(ZFC)。我们将了解几个核心公理,包括外延公理、幂集公理、分离公理模式和基础公理,并探讨它们如何帮助我们避免像罗素悖论这样的逻辑矛盾。我们将使用谓词逻辑公式来精确描述这些公理。

概述 📋

ZFC公理系统定义了集合论的标准理论,被广泛接受为发展所有数学的可靠基础。本节我们将重点介绍其中几个关键公理,并通过练*书写谓词公式来加深理解。

外延公理

上一节我们介绍了集合论的基础概念,本节中我们来看看第一个核心公理——外延公理。它抓住了“一个集合由其成员唯一决定”的思想。

假设有两个集合 yz,断言它们具有相同的元素。我们可以用谓词公式将其表述为:

∀x. (x ∈ y ↔ x ∈ z)

这个公式可以作为集合相等的定义:当且仅当两个集合拥有完全相同的成员时,我们说它们是相等的。

我们甚至不需要将“相等”作为逻辑语言的基本部分并为其添加公理。外延公理足以涵盖这一点,它表述为:如果两个集合有相同的成员,那么它们属于完全相同的其他集合。用公式表示是:

∀x, y, z. ( (∀w. (w ∈ x ↔ w ∈ y)) → (x ∈ z ↔ y ∈ z) )

这是集合论的一个基本起点公理。

幂集公理

理解了集合的相等性后,我们来看看如何构造更复杂的集合。幂集公理指出:每个集合都有一个幂集

用谓词集合论的语言来说,即:对于每一个集合 x,都存在一个集合 p(即 x 的幂集),使得对于任意集合 ssx 的子集当且仅当 sp 的成员。我们知道如何仅用“属于”关系()来表达“sx 的子集”:∀a. (a ∈ s → a ∈ x)

因此,幂集公理的公式化表述是:

∀x. ∃p. ∀s. ( (∀a. (a ∈ s → a ∈ x)) ↔ s ∈ p )

这个公理断言,确实存在一个集合 p,它恰好由 x 的所有子集组成,这个集合 p 就称为 x 的幂集。

分离公理模式(子集公理)

在尝试处理像“所有满足性质 P 的集合”这类定义时,我们曾遇到罗素悖论。分离公理模式提供了一个安全的方法来构造子集。

它基本上是说:如果 S 是一个已知的集合,P(x) 是集合论中的一个谓词(即使是像“x ∉ x”这样可能危险的表述),那么从 S 中分离出那些满足 P(x) 的元素,仍然构成一个集合。

换句话说,{x ∈ S | P(x)} 是一个集合。用公式表示:

∀S. ∃Y. ∀x. (x ∈ Y ↔ (x ∈ S ∧ P(x)))

这之所以重要,是因为它限制了概括的范围。引发罗素悖论的是无限制的概括:尝试构造所有满足 P(x)x 的集合({x | P(x)})。分离公理模式通过要求 x 必须来自一个预先存在的集合 S,从而避免了这个问题。

基础公理(正则公理)

为了解决自属性和自引用的问题,集合论引入了基础公理。其直观思想是:集合的元素必须先于集合本身存在,或者说,集合应由更简单的元素构建。

特别地,一个集合不能是它自身的成员,因为它不能由自身构建。事实上,你甚至不能有一个集合,它是其自身成员的成员(即 x ∈ y ∈ x 这类循环)。所有这类间接的成员资格都被禁止。

一个优雅的表述方式是:在属于关系(∈)下,所有集合都是良基的。这意味着你找不到一个无限的集合序列,其中每个集合都是下一个集合的成员。

为了精确表述,我们先定义“∈-极小元”:设 xy 的一个∈-极小元,表示 x ∈ y,但 x 中没有任何元素属于 y。换句话说,x 是由不属于 y 的东西构成的,但 x 本身在 y 中。用公式定义:

Min∈(x, y) ≔ (x ∈ y) ∧ (∀z ∈ x. z ∉ y)

基础公理则断言:每个非空集合都有一个∈-极小元

∀x. (x ≠ ∅ → ∃y. Min∈(y, x))

这是整数良序原理(每个非负整数集都有最小元)的推广。基础公理意味着不存在无限递减的属于链(如 ... ∈ x₃ ∈ x₂ ∈ x₁)。

基础公理的重要推论

学*了基础公理的内容后,我们来看看它能立即得出哪些重要结论。

基础公理可以很快推导出:没有集合是它自身的成员

证明如下:假设存在一个集合 S,使得 S ∈ S。考虑单元素集合 R = {S}R 非空,根据基础公理,R 必须有一个∈-极小元。R 中唯一的元素是 S,所以这个极小元只能是 S。但根据∈-极小元的定义,S 中的任何元素都不应在 R 中。然而,我们假设了 S ∈ S,这意味着 S 中有一个元素(即 S 自身)属于 R(因为 S ∈ R)。这与 SR 的∈-极小元矛盾。因此,假设不成立,S ∉ S

这个论证可以推广,同样能证明不存在像 A ∈ B ∈ A 这样的成员循环。

从“没有集合是自身成员”这一结论,我们可以立即得到两个重要推论:

  1. 所有集合的集合不能是一个集合。因为如果“所有集合的集合”是一个集合,那么它将是自身的一个成员,而这刚刚被证明是不可能的。
  2. 回顾罗素悖论中的集合 WW = {x | x ∉ x}。现在我们发现,由于没有集合是自身的成员,那么“不是自身成员的集合”就是所有集合。因此,W 就是“所有集合的集合”。既然“所有集合的集合”不是集合(由推论1得出),那么 W 也就不是一个集合。这从另一个角度解决了罗素悖论。

总结 🎯

本节课中我们一起学*了ZFC集合论中的几个关键公理:

  • 外延公理:定义了集合的相等性。
  • 幂集公理:确保每个集合的幂集存在。
  • 分离公理模式:允许我们从一个已知集合中安全地分离出满足特定性质的子集,从而避免了无限制概括导致的悖论。
  • 基础公理:要求集合在属于关系下是良基的,这直接否定了集合自属性和无限属于链的可能性,并由此解决了“所有集合的集合”这类悖论。

这些公理共同为数学提供了一个稳固、无矛盾的基础。

数论基础:1:课程概述与基本公理

在本节课中,我们将开始学*数论,并以此作为练*数学证明的绝佳领域。数论是一个自成一体的基础学科,包含许多优雅的证明和结构。我们将应用矛盾法、归纳法以及良序原理。本单元的最终目标是理解RSA密码系统的工作原理。今天,我们将建立一个关于整数质因数分解的基本事实,这是一个值得证明的定理。在作业中,我们将展示一个不具备唯一因式分解性质的数字系统。最终,我们将能彻底厘清相关概念。

数论基础:2:基本代数规则与除法定理

上一节我们介绍了课程目标,本节中我们来看看我们将默认使用的基本代数规则。

我们将假设所有关于加法、乘法和减法的标准代数规则都成立。例如:

  • 分配律a * (b + c) = a*b + a*c
  • 乘法交换律a * b = b * a
  • 乘法结合律(a * b) * c = a * (b * c)
  • 加法单位元a + 0 = a
  • 加法逆元a + (-a) = 0

这些是标准代数事实,我们将视为理所当然。


此外,我们还将接受除法定理作为一个公理。对于整数 a 和正整数 b,存在唯一的整数商 q 和余数 r,满足:

a = b * q + r

其中余数 r 满足 0 ≤ r < b。这个定理是基本的,其证明(例如通过归纳法)虽然可行,但在此我们将其作为基础接受。

数论基础:3:整除关系及其性质

上一节我们明确了基本规则,本节中我们来看看整数间一个核心关系:整除。

在接下来的一周左右,所有变量都默认为整数。我们定义整除关系:c | a(读作“c整除a”)当且仅当存在某个整数 k,使得 a = k * c

  • 同义词ca 的除数;ac 的倍数。
  • 示例
    • 5 整除 15,因为 15 = 3 * 5
    • 任何数 n 都整除 0,因为 0 = 0 * n。所以0是任何数的倍数。


从定义可以直接推导出一些简单性质:

  1. 如果 c | a,那么对于任意整数 s,有 c | (s * a)
  2. 如果 c | ac | b,那么 c | (a + b)

让我们验证性质2。已知 c | a 意味着 a = k1 * cc | b 意味着 b = k2 * c。那么:

a + b = (k1 * c) + (k2 * c) = (k1 + k2) * c

因此 c 整除 (a + b)

综合以上,我们得到一个重要结论:如果 c | ac | b,那么对于任意整数 stc 都整除 (s*a + t*b)。形如 s*a + t*b 的表达式称为 ab 的一个线性组合

所以,我们的结论可以重新表述为:ab 的任何一个公约数,都必定整除 ab 的任意线性组合。请记住这个关键事实。

数论基础:4:最大公约数

上一节我们讨论了整除和线性组合,本节中我们聚焦于一个核心概念:最大公约数。

ab最大公约数,记作 gcd(a, b),是能同时整除 ab 的最大正整数。根据良序原理,这个最大公约数总是存在的(因为公约数集合是非负整数集的一个有界子集,且至少包含1)。

以下是几个例子:

  • gcd(10, 12) = 2。(因为10=2×5,12=2×6,公共部分只有2)
  • gcd(13, 12) = 1。(因为13是质数,与12无大于1的公因数)
  • 对于任意正整数 ngcd(0, n) = n。(因为任何数都整除0,n 本身是最大的公约数)
  • 对于质数 pgcd(p, a) 要么是1(如果 p 不整除 a),要么是 p(如果 p 整除 a)。


本节课中我们一起学*了数论的基本起点:我们明确了将使用的代数公理和除法定理,定义了整除关系并推导出其基本性质,特别是关于线性组合的关键结论,最后引入了最大公约数的概念并观察了一些例子。这些概念是后续深入学*数论和证明的基石。

计算机科学的数学基础:L2.1.2:欧几里得算法 🧮

在本节课中,我们将学*如何高效地计算两个数的最大公约数。我们将重点介绍一个古老而强大的算法——欧几里得算法,并理解其背后的数学原理和运行机制。

核心概念:余数引理

欧几里得算法基于一个关键的数学引理,我们称之为余数引理。该引理指出:对于两个整数 ab(其中 b ≠ 0),ab 的最大公约数等于 ba 除以 b 的余数的最大公约数。

用公式表示如下:

gcd(a, b) = gcd(b, a mod b)

这个引理为何成立?我们可以通过除法算式来理解。根据除法运算,存在整数商 q 和余数 r,使得:

a = q * b + r

其中 0 ≤ r < b

从这个等式可以看出,任何能同时整除 br 的数,也必然能整除 a。反之,任何能同时整除 ab 的数,也必然能整除 r。因此,ab 的公因数集合与 br 的公因数集合完全相同,它们的最大公约数自然也相同。这就证明了余数引理。

算法过程:一个具体例子

上一节我们介绍了余数引理,本节中我们来看看如何利用它来计算最大公约数。让我们通过一个具体例子来演示欧几里得算法的步骤。

假设我们要计算 gcd(899, 493)

以下是计算步骤:

  1. 计算 899 ÷ 493,商为 1,余数为 406。根据引理,gcd(899, 493) = gcd(493, 406)
  2. 计算 493 ÷ 406,商为 1,余数为 87。因此,gcd(493, 406) = gcd(406, 87)
  3. 计算 406 ÷ 87,商为 4,余数为 58。因此,gcd(406, 87) = gcd(87, 58)
  4. 计算 87 ÷ 58,商为 1,余数为 29。因此,gcd(87, 58) = gcd(58, 29)
  5. 计算 58 ÷ 29,商为 2,余数为 0。因此,gcd(58, 29) = gcd(29, 0)

根据定义,任何非零整数 x0 的最大公约数就是 x 本身(gcd(x, 0) = x)。所以,gcd(29, 0) = 29

通过这一系列步骤,我们得出 gcd(899, 493) = 29。这个算法之所以高效,是因为每一步的余数都在快速减小。

状态机视角:验证算法正确性

理解了算法的计算过程后,我们可以从一个更形式化的角度——状态机模型——来审视它,并验证其正确性。

我们可以将欧几里得算法定义为一个简单的状态机:

  • 状态:由一对非负整数 (x, y) 表示。
  • 起始状态(a, b),即我们想要求最大公约数的两个原始数。
  • 状态转移规则:如果当前状态为 (x, y)y ≠ 0,则下一状态变为 (y, x mod y)。如果 y = 0,则算法终止。

这个状态机有一个非常重要的不变性:在任何状态 (x, y) 下,gcd(x, y) 的值都等于起始状态的 gcd(a, b)。这是因为根据余数引理,每次状态转移都保持了最大公约数不变。

这个不变性在起始状态 (a, b) 时显然成立。根据不变性原理,如果算法终止,终止状态的不变性依然成立。算法终止时,y 必然为 0。此时,gcd(x, 0) = x。根据不变性,x 就等于我们最初要求的 gcd(a, b)。这就证明了算法的部分正确性:如果算法终止,那么它计算出的结果一定是正确的。

算法分析:为何如此高效?

我们已经证明了算法的正确性,现在来分析它的效率。欧几里得算法为什么能快速终止?

关键在于观察每一步中数字 y 的变化。在状态转移 (x, y) -> (y, x mod y) 中:

  • 情况一:如果 y ≤ x/2,那么下一步的 x(即当前的 y)已经至少减半。
  • 情况二:如果 y > x/2,那么余数 x mod y = x - y。由于 y > x/2,所以 x - y < x/2。这意味着下一步的 y(即当前的余数)将小于 x/2

综合来看,每经过至多两步y 的值至少会减半。因此,算法的步骤数不会超过 2 * log₂(b)(其中 b 是起始的第二个数),这大致等于 b 的二进制表示的位数。所以,欧几里得算法是一个对数时间复杂度的算法,效率非常高。


本节课中我们一起学*了欧几里得算法。我们从余数引理这个核心数学原理出发,通过一个例子演示了算法的计算步骤。接着,我们将其形式化为一个状态机模型,并利用不变性原理证明了算法的正确性。最后,我们分析了算法的效率,指出其对数级的时间复杂度,这使得计算大整数的最大公约数变得非常高效。这个古老的算法是许多现代密码学技术的数学基础之一。

计算机科学的数学基础:L2.1.4:Pulverizer(扩展欧几里得算法)🔢

在本节课中,我们将要学*一个被称为 Pulverizer(粉碎机) 的算法,它也被称为扩展欧几里得算法。我们将看到它如何高效地找到两个整数的最大公约数(GCD),并同时计算出满足特定线性组合关系的系数 st

概述

上一节我们介绍了欧几里得算法和线性组合的概念。本节中,我们将看看如何扩展欧几里得算法,使其不仅能计算最大公约数,还能找到对应的系数。这个扩展算法就是 Pulverizer

算法目标与原理

我们的目标是证明并实现一个核心定理:对于任意两个整数 ab,它们的最大公约数 gcd(a, b) 可以表示为 ab 的线性组合。即,存在整数 st,使得:

公式: gcd(a, b) = s * a + t * b

Pulverizer 算法使我们能够高效地找到这样的系数 st。其基本思想是:在执行标准欧几里得算法的过程中,同时追踪一组额外的系数,这些系数记录了当前数值如何表示为原始 ab 的线性组合。

算法步骤详解

以下是 Pulverizer 算法的具体执行步骤。我们将通过维护一组系数来追踪线性组合关系。

初始化

算法开始时,我们有两个寄存器 xy,分别初始化为 ab。同时,我们需要维护四个系数 c, d, e, f,使得以下关系始终成立:

  • x = c * a + d * b
  • y = e * a + f * b

初始状态很简单:

  • x = a = 1*a + 0*b,所以 c=1, d=0
  • y = b = 0*a + 1*b,所以 e=0, f=1

迭代更新

欧几里得算法的每一步是计算 x 除以 y 的商 q 和余数 r,然后更新 (x, y)(y, r)

在 Pulverizer 中,我们不仅要更新数值,还要更新对应的系数:

  1. 新的 x 就是旧的 y。因此,新的系数 (c新, d新) 就等于旧的 (e, f)
  2. 新的 y 是余数 r,计算公式为 r = x - q * y。由于 xy 都可以表示为 ab 的线性组合,那么 r 也可以:
    公式: r = (c*a + d*b) - q * (e*a + f*b) = (c - q*e)*a + (d - q*f)*b
    因此,新的系数 (e新, f新) 就等于 (c - q*e, d - q*f)

算法终止

当余数 r 为 0 时,算法终止。此时,y 的值就是 gcd(a, b),而对应的系数 (e, f) 就是我们寻找的 (s, t),满足 gcd(a, b) = e*a + f*b

实例演示

让我们通过一个具体例子 a=899, b=493 来演示这个过程。下表追踪了每一步的数值和系数变化:

步骤 x (值) y (值) 商 q 余数 r c d e f 说明
初始 899 493 - - 1 0 0 1 x=1*a+0*b, y=0*a+1*b
1 493 406 1 406 0 1 1 -1 r = x - q*y = 899-1*493=406
e新=1-1*0=1, f新=0-1*1=-1
2 406 87 1 87 1 -1 -1 2 r = 493-1*406=87
e新=0-1*1=-1, f新=1-1*(-1)=2
3 87 58 4 58 -1 2 5 -9 r = 406-4*87=58
e新=1-4*(-1)=5, f新=-1-4*2=-9
4 58 29 2 29 5 -9 -11 20 r = 87-1*58=29
e新=-1-1*5=-6, f新=2-1*(-9)=11
5 29 0 2 0 -6 11 - - r = 58-2*29=0,算法终止

算法在余数为 0 时停止。此时,y=29 即为 gcd(899, 493)。对应的系数 e=-6, f=11 满足:
公式: gcd(899, 493) = 29 = (-6) * 899 + 11 * 493

系数调整技巧

从例子中我们看到,得到的系数 s = -6 是负数。如果我们希望得到一个正系数的表达式,有一个简单的技巧:因为 gcd(a,b) = s*a + t*b,我们可以在 s 上加上 b 的倍数,同时在 t 上减去 a 的相同倍数,其值保持不变。

公式: gcd(a,b) = (s + k*b)*a + (t - k*a)*b,其中 k 是任意整数。

例如,取 k=1

  • s = -6 + 493 = 487
  • t = 11 - 899 = -888
    于是我们得到另一个有效的表达式:29 = 487 * 899 + (-888) * 493。这样我们就得到了一个正系数。

算法效率

Pulverizer 算法与标准欧几里得算法具有相同的效率级别。它的时间复杂度是 O(log min(a, b)),具体来说,所需的算术运算次数与 ab 的二进制位长度成正比。这意味着即使对于非常大的数字,它也能非常高效地运行。

总结

本节课中我们一起学*了 Pulverizer(扩展欧几里得算法)。我们了解到:

  1. 该算法在计算 gcd(a, b) 的同时,能高效地找到系数 st,使得 gcd(a, b) = s*a + t*b
  2. 其核心是在欧几里得算法的迭代过程中,维护并更新一组表示线性组合关系的系数。
  3. 通过一个简单的数学技巧,我们可以调整得到的系数,例如获得正系数的表达式。
  4. 该算法非常高效,时间复杂度是对数级的,适用于解决需要线性组合系数的数论问题。

这个算法是解决许多数论和密码学问题的基础工具,例如求解模线性方程。在接下来的课程中,我们将看到它的具体应用。

计算机科学的数学基础:P38:L2.1.6- 重温《虎胆龙威》💧

在本节课中,我们将基于《虎胆龙威》水壶问题的状态机分析,推导出两个重要的结论。我们将探讨在给定规则下,水壶中可能达到的水量范围,并理解其背后的数学原理。

上一节我们介绍了状态机在《虎胆龙威》问题中的应用,本节中我们来看看如何从这些分析中得出一般性的结论。

核心发现

通过分析《虎胆龙威》的状态机,我们发现在其规则下,任何阶段每个水壶中的水量,都是水壶容量A和B的线性组合

用公式表示,在任何一系列操作后,水壶中的水量可以表示为:
水量 = s * A + t * B
其中st是整数。

一个关键点是,最大公约数(GCD) 整除A和B的任何线性组合。这为我们理解可能获得的水量范围提供了重要线索。

可达水量的完整描述

事实上,只要线性组合的结果能装进水壶(即非负且小于水壶容量),该水量就是可达的。

换句话说,你可以得到A和B的任何线性组合,前提是它能被容纳在某个水壶中。

让我们看看如何实现这一点。假设我们有一个线性组合 s*A + t*B,并且它满足 0 ≤ s*A + t*B < B,这意味着它可以被装进B水壶。

以下是实现该水量的步骤:

  1. 重复将A水壶装满,然后将其中的水倒入B水壶。
  2. 每当B水壶被装满时,就将其倒空。
  3. 持续这个过程,直到B水壶中得到我们想要的水量。

在这个过程中,装满A水壶的总次数是s次。从水源获得的总水量是 s * A。B水壶被倒空的次数必须是 -t 次(注意t是负数,所以-t是正数)。最终,B水壶中剩余的水量正好是 s*A + t*B

实际上,你甚至不需要预先知道st的具体值。你只需要持续执行“装满A,倒入B,B满则清空”的循环,并监控B水壶中的水量,直到达到目标值即可。

本节课中我们一起学*了如何从《虎胆龙威》水壶问题的状态机分析中,推导出水量的可达性定理。我们证明了在给定规则下,水壶中可达的水量正是其容量的线性组合,并且可以通过一个简单的迭代过程获得任何符合条件的线性组合值。这为我们理解此类问题的本质提供了清晰的数学框架。

计算机科学的数学基础:L2.1.7:素因数分解定理

在本节课中,我们将学*算术基本定理,即素因数分解定理。我们将探讨其核心引理,并学*如何证明每个大于1的整数都可以唯一地分解为素数的乘积。


核心引理:素数整除乘积的性质

上一节我们介绍了素数的概念,本节中我们来看看素数的一个关键性质。这个引理是证明素因数分解定理的基础。

引理:如果 p 是一个素数,并且 p 整除两个整数 ab 的乘积 a * b,那么 p 必定整除 a 或整除 b

我们不能直接使用素因数分解来证明这个引理,因为我们正要用它来证明素因数分解定理本身。因此,我们需要基于最大公约数(GCD)的知识进行证明。

证明
假设 p 整除 a * b,但 p 不整除 a。由于 p 是素数,其正因子只有 1p 本身。既然 p 不整除 a,那么 ap 的最大公约数 gcd(a, p) = 1

根据裴蜀定理,存在整数 st,使得以下线性组合成立:

s * a + t * p = 1

现在,将等式两边同时乘以 b

s * (a * b) + t * p * b = b

观察等式左边:

  • 第一项 s * (a * b) 包含 a * b,而 p 整除 a * b,所以第一项是 p 的倍数。
  • 第二项 t * p * b 显式地包含因子 p,所以它也是 p 的倍数。

因此,等式左边是 p 的倍数之和,所以它本身也是 p 的倍数。这意味着等式右边 b 也必须是 p 的倍数。由此证明,p 整除 b

这个优雅的证明是我们证明唯一分解定理的关键。


引理的推论

基于上述引理,我们可以得到一个有用的推论。

推论:如果一个素数 p 整除多个整数的乘积 a1 * a2 * ... * am,那么 p 至少整除其中一个因子 ai

这个推论可以通过数学归纳法证明,其基础情况(m=2)正是我们刚刚证明的引理。


算术基本定理(素因数分解定理)

现在,我们准备证明本节课的核心——算术基本定理。

定理:每一个大于1的整数 n,都可以唯一地表示为一系列弱递减(即非递增)的素数的乘积。

“弱递减”这个技术性描述是为了精确表达唯一性。它意味着,如果我们把所有素因子(包括重复出现的)按从大到小的顺序排列,那么这个序列是唯一的。

公式表示

n = p1 * p2 * ... * pk

其中 p1 ≥ p2 ≥ ... ≥ pk,且每个 pi 都是素数。

举例
数字 123456 可以分解为:

123456 = 2^6 * 3^1 * 643^1

按弱递减序列排列其素因子(考虑重复次数),我们得到序列:643, 3, 2, 2, 2, 2, 2, 2。这是表示 123456 的唯一方式。


定理的证明(反证法)

我们使用反证法来证明唯一性。

  1. 假设存在反例:假设存在一个大于1的最小整数 N,它有两种不同的素因数分解方式。

    N = p1 * p2 * ... * pk = q1 * q2 * ... * qm
    

    其中 p 序列和 q 序列都是弱递减的素数序列,但这两个序列不相同。

  2. 比较第一个素因子

    • 如果 p1 = q1,那么我们可以从等式两边同时约去 p1,得到一个更小的数 N / p1 也具有两种不同的分解,这与 N 是最小反例的假设矛盾。
    • 因此,p1q1 必然不相等。不妨假设 q1 > p1
  3. 推导矛盾

    • 由于 q1 > p1,且 p 序列是弱递减的,所以 q1 大于 p 序列中的每一个素数 pi
    • 观察等式 N = p1 * p2 * ... * pk。因为 q1 整除 Nq1N 的一个因子),根据前面的推论q1 必须整除某个 pi
    • 但是,q1 是一个素数且 q1 > pi,一个较大的素数不可能整除一个较小的素数(因为素数只能被1和自身整除)。这产生了矛盾。
  4. 结论:最初的假设是错误的。不存在这样的反例 N。因此,每个大于1的整数的素因数分解方式都是唯一的。


总结

本节课中我们一起学*了:

  1. 核心引理:素数整除乘积的性质及其证明,该证明巧妙地运用了线性组合。
  2. 算术基本定理:每个大于1的整数都有唯一(按弱递减序列排列)的素因数分解。
  3. 定理证明:通过“最小反例”的反证法,结合核心引理,严谨地证明了分解的唯一性。

素因数分解定理是数论的基石,在计算机科学的诸多领域,如密码学、算法分析中都有根本性的应用。

计算机科学的数学基础:2.2.1:同余模n 📐

在本节课中,我们将学*数论中的一个核心概念——同余。这个概念由高斯在18世纪初提出,至今仍在计算机科学,特别是加密和哈希等领域有广泛应用。我们将从定义开始,逐步理解其性质和应用。

同余的定义

同余是两个整数 ab 之间的一种关系,它由另一个大于1的整数 n 决定。

定义:如果 n 整除 (a - b),即 (a - b)n 的倍数,则称 abn 同余。记作:
a ≡ b (mod n)

这是一个关键定义。例如,30 ≡ 12 (mod 9),因为 30 - 12 = 18,而 9 整除 18

同余的等价表述

理解同余的另一种方式是:两个数模 n 同余,当且仅当它们除以 n 的余数相同。

引理a ≡ b (mod n) 当且仅当 ab 除以 n 的余数相同。

我们可以用这个引理来验证之前的例子:30 除以 9312 除以 9 也余 3,因此它们模 9 同余。

上一节我们介绍了同余的基本定义,本节中我们来证明这个关键的等价引理。

引理的证明

证明
a 除以 n 的商为 q_a,余数为 r_ab 除以 n 的商为 q_b,余数为 r_b。根据除法算法,有:
a = q_a * n + r_a
b = q_b * n + r_b
其中 0 ≤ r_a, r_b < n

  • 充分性(右推左):如果 r_a = r_b,那么 a - b = (q_a - q_b) * n。显然 n 整除 (a - b),所以 a ≡ b (mod n)
  • 必要性(左推右):如果 a ≡ b (mod n),即 n 整除 (a - b)。将 ab 的表达式代入:
    a - b = (q_a - q_b) * n + (r_a - r_b)
    由于 n 整除 (a - b)(q_a - q_b) * n,因此 n 也必须整除 (r_a - r_b)。但 r_ar_b 都在 [0, n) 区间内,它们的差 (r_a - r_b) 的绝对值小于 n。在 (-n, n) 区间内,能被 n 整除的数只有 0。因此 r_a - r_b = 0,即 r_a = r_b

证毕。这个引理非常重要,它意味着我们可以用“余数相等”来理解和操作同余。

同余的基本性质

由于同余本质上意味着余数相等,它继承了等式的许多良好性质。

以下是同余关系的三个基本性质:

  1. 自反性:对于任意整数 a,有 a ≡ a (mod n)
  2. 对称性:如果 a ≡ b (mod n),那么 b ≡ a (mod n)
  3. 传递性:如果 a ≡ b (mod n)b ≡ c (mod n),那么 a ≡ c (mod n)

这些性质很容易从“余数相等”的角度理解。例如,传递性:ab 余数相同,bc 余数相同,自然 ac 余数也相同。

余数引理与算术运算

一个非常有用的技术结果是余数引理:任何整数 a 都与其自身除以 n 的余数 rn 同余。即 a ≡ r (mod n),其中 r = a % n

证明:根据定义,ar 除以 n 的余数都是 r,因此由之前的引理可知它们同余。

这个引理是余数算术的基础,它允许我们在同余计算中,随时用一个更小的余数来替换原数。

更重要的是,同余与加法、乘法运算兼容。这意味着我们可以像处理普通等式一样处理同余式。

以下是同余运算的规则:

  • 加法规则:如果 a ≡ b (mod n),那么对于任意整数 c,有 a + c ≡ b + c (mod n)
  • 乘法规则:如果 a ≡ b (mod n),那么对于任意整数 c,有 a * c ≡ b * c (mod n)
  • 加法组合规则:如果 a ≡ b (mod n)c ≡ d (mod n),那么 a + c ≡ b + d (mod n)
  • 乘法组合规则:如果 a ≡ b (mod n)c ≡ d (mod n),那么 a * c ≡ b * d (mod n)

推论:在进行模 n 的算术时(无论是加法、乘法还是它们的组合),我们可以在任何步骤将任意一个数替换为与其同余的数(通常替换为它的余数),最终结果的同余性保持不变。这使得计算涉及大数的模运算变得非常简单。

应用示例

让我们应用所学知识解决一个具体问题:计算 287^9 mod 4 的值。

  1. 简化底数:首先计算 287 mod 4287 ÷ 4 = 71 ... 3,所以 287 ≡ 3 (mod 4)。根据乘法规则,287^9 ≡ 3^9 (mod 4)
  2. 简化指数:计算 3^2 = 99 mod 4 = 1,所以 3^2 ≡ 1 (mod 4)
  3. 分解指数3^9 = 3^(2*4+1) = (3^2)^4 * 3^1
  4. 代入计算:因为 3^2 ≡ 1 (mod 4),所以 (3^2)^4 ≡ 1^4 ≡ 1 (mod 4)。因此,3^9 ≡ 1 * 3 ≡ 3 (mod 4)

所以,287^9 mod 4 = 3。通过使用同余性质,我们避免了直接计算 287^9 这个巨大数字。

总结

本节课中我们一起学*了同余模n的概念。

  • 我们掌握了同余的两种等价定义:n | (a-b)ab 除以 n 的余数相同。
  • 我们探讨了同余的自反性、对称性和传递性。
  • 我们学*了关键的余数引理,以及同余与加法、乘法运算的兼容性规则。这些规则构成了余数算术的基础,允许我们在计算中用更小的余数替换大数。
  • 最后,我们通过一个计算 287^9 mod 4 的例子,演示了如何运用这些规则高效地解决模运算问题。

理解同余是学*后续数论知识以及在计算机科学中应用相关算法(如加密)的重要基石。

计算机科学的数学基础:2.2.3:模n的逆元 🔢

在本节课中,我们将要学*模n运算(即余数算术)中的一个核心概念——逆元。我们将探讨为什么在模运算中不能随意“消去”一个数,以及何时可以安全地进行消去。理解逆元是掌握模运算中乘法和除法行为的关键。

上一节我们介绍了模n运算的基本同余规则,它使得加法与乘法运算与普通算术非常相似。本节中我们来看看模运算与普通算术的一个主要区别:消去律并不总是成立。

模运算中的消去问题

我们从一个具体的例子开始。在模10的运算中,有:
8 * 2 ≡ 16 ≡ 6 (mod 10)
同时:
3 * 2 ≡ 6 (mod 10)
因此,8 * 2 ≡ 3 * 2 (mod 10)

如果像在普通算术中一样,我们尝试在等式两边消去2,就会得到 8 ≡ 3 (mod 10) 的结论,这显然是错误的。

核心结论:在模n运算中,你不能随意消去等式两边相同的乘数。

何时可以消去?逆元的概念

那么,关键问题来了:我们何时可以安全地消去一个数k呢?答案是:当数k在模n下有逆元时。

一个数k在模n下的逆元,记作 k',是一个满足以下等式的整数:
k * k' ≡ 1 (mod n)
你可以将 k' 理解为模n世界里的 1/k,只不过它是一个整数。

定理:数k在模n下存在逆元,当且仅当 kn 互质(即 gcd(k, n) = 1)。

如何找到逆元?扩展欧几里得算法

如何找到这个逆元 k' 呢?这基于一个重要的数论事实:如果 kn 互质,那么存在整数 st,使得:
s * k + t * n = 1
这个等式称为贝祖等式,可以通过扩展欧几里得算法求得 st

让我们仔细看看这个等式在模n下的含义:

  1. 等式 s*k + t*n = 1 在整数中成立。
  2. 将其转换为模n同余式:s*k + t*n ≡ 1 (mod n)
  3. 由于 n ≡ 0 (mod n),所以 t*n ≡ 0 (mod n)
  4. 因此,上式简化为:s * k ≡ 1 (mod n)

看!根据逆元的定义,这里的系数 s 就是 k 在模n下的逆元 k'。所以,求逆元的过程就是求解贝祖等式 s*k + t*n = 1 中的系数 s

利用逆元进行消去

一旦我们有了逆元 k',消去操作就变得合法了。假设我们有:
a * k ≡ b * k (mod n)
并且 kn 互质,其逆元为 k'

以下是消去步骤:

  1. 在等式两边同时乘以 k'(a * k) * k' ≡ (b * k) * k' (mod n)
  2. 根据结合律:a * (k * k') ≡ b * (k * k') (mod n)
  3. 因为 k * k' ≡ 1 (mod n),所以得到:a * 1 ≡ b * 1 (mod n)
  4. 最终结果:a ≡ b (mod n)

这样,我们就成功地消去了 k

核心规则总结

以下是关于模n运算中消去律的核心要点:

  • 可消去条件:一个数 k 可以在模n运算中被消去,当且仅当 k 在模n下存在逆元。
  • 等价表述k 可消去当且仅当 kn 互质(即 gcd(k, n) = 1)。
  • 求逆方法:通过解贝祖等式 s*k + t*n = 1(使用扩展欧几里得算法),得到的 s 即为 k 模n的逆元。
  • 消去操作:当 a*k ≡ b*k (mod n)kn 互质时,在等式两边乘以 k 的逆元,即可得到 a ≡ b (mod n)

本节课中我们一起学*了模n运算中逆元的概念及其重要性。我们明白了为什么不能随意消去,并掌握了判断一个数是否可消去的方法(检查是否与模数n互质),以及如何通过扩展欧几里得算法找到逆元来执行合法的消去操作。这是理解模运算代数结构的基础。

计算机科学的数学基础:2.3:模幂运算与欧拉函数

概述

在本节中,我们将学*模运算中一个非常重要的概念——欧拉函数。我们将了解它的定义、如何计算,并初步认识它在欧拉定理中的作用。理解欧拉函数是掌握后续模幂运算和密码学基础的关键。

欧拉函数的定义

上一节我们讨论了模运算中的逆元。具有模逆元的元素对我们特别重要,因此第一个问题是:这样的元素有多少个?这就是欧拉函数告诉我们的。

n 为一个正整数。n 的欧拉函数 φ(n) 定义为:在从 0n-1 的余数区间内,与 n 互质的整数 k 的数量。

另一种说法是,φ(n) 计算的是与 n 互质的数的个数。我们定义一组我们感兴趣的数字:{k | 0 ≤ k < n 且 gcd(k, n) = 1}。这个集合的大小就是 φ(n)

φ(n) 也称为欧拉函数,我们常称之为 phi 或欧拉 φ 函数。

计算欧拉函数:示例

让我们通过几个例子来理解如何计算 φ(n)

示例1:n = 7
因为 7 是质数,所有小于 7 的正整数(即 16)都与 7 互质。因此,φ(7) = 6

示例2:n = 12
我们需要找出在 011 中,哪些数与 12 没有公因子(除了1)。这些数是 1, 5, 7, 11。其他数(如 2, 3, 4, 6, 8, 9, 10)与 12 有公因子。因此,φ(12) = 4

计算欧拉函数的规则

了解了基本定义后,我们来看看如何系统地计算 φ(n)。以下是针对不同情况的规则。

规则1:当 n 是质数时

如果 p 是质数,那么所有小于 p 的正整数都与 p 互质。因此:

φ(p) = p - 1

规则2:当 n 是质数的幂时

让我们看一个更重要的例子:计算 φ(9)。候选数字是从 08。一个数 k9 互质,当且仅当它与 3 互质(因为 9 = 3²)。在 08 的区间内,哪些数不与 3 互质?每三个数中就有一个能被 3 整除(即 0, 3, 6)。这些是“坏”的数。所以,“好”的(与 9 互质的)数的数量就是总数减去坏的数量。

这推广到任意质数的幂。如果 p 是质数,k 是正整数,那么:

φ(p^k) = p^k - p^{k-1}

推导:一个数相对于 p^k 是互质的,当且仅当它对 p 是互质的。在 0p^k - 1 的区间内,每 p 个数中就有一个能被 p 整除(即不与 p 互质)。这样的数有 p^k / p = p^{k-1} 个。因此,互质的数的数量为 p^k - p^{k-1}

规则3:欧拉函数的乘性

假设你处理的数字不是质数的幂。关于 φ 函数有一个非常优雅的性质,它解释了如何处理非质数幂的情况。

如果 ab 互质(即 gcd(a, b) = 1),那么:

φ(a * b) = φ(a) * φ(b)

这个性质称为乘性。在数论中,如果一个函数在互质的输入上的值等于各输入值的乘积,则该函数是乘法的。φ 函数就是乘法的。

这个性质的证明会在*题集或后续关于计数与容斥原理的课程中看到。现在,让我们利用这个性质来计算任意数字的 φ 值。

应用乘性计算欧拉函数

让我们利用 φ 的乘性来计算之前看起来复杂的 φ(12)

因为 12 = 3 * 4,且 gcd(3, 4) = 1,所以:

φ(12) = φ(3) * φ(4)

现在问题简化了:

  • 3 是质数,所以 φ(3) = 3 - 1 = 2
  • 4 是质数 2 的幂(),所以 φ(4) = 2² - 2^{2-1} = 4 - 2 = 2

因此:

φ(12) = 2 * 2 = 4

这与我们之前通过列举得到的结果一致。

欧拉函数的重要性:通向欧拉定理

我们为什么要关心欧拉函数 φ(n) 呢?关键在于欧拉定理

欧拉定理告诉我们,与 n 互质的数的幂在模 n 下的行为。具体来说:

如果整数 kn 互质(即 gcd(k, n) = 1),那么将 k 提升到 φ(n) 次方后,其结果与 1n 同余。
用公式表示为:如果 gcd(k, n) = 1,则 k^{φ(n)} ≡ 1 (mod n)

这个定理是RSA加密算法等现代密码学技术的基石,它引导我们进入下一节关于模幂运算和其应用的深入学*。

总结

本节课我们一起学*了欧拉函数 φ(n)。我们首先明确了它的定义:小于 n 且与 n 互质的正整数的个数。接着,我们掌握了计算 φ(n) 的三个关键规则:

  1. 对于质数 pφ(p) = p - 1
  2. 对于质数的幂 p^kφ(p^k) = p^k - p^{k-1}
  3. 对于互质的两个数 abφ 函数具有乘性:φ(a*b) = φ(a) * φ(b)

最后,我们了解到欧拉函数的核心价值在于它是欧拉定理的关键组成部分,该定理描述了互质数在模幂运算中的周期性,为后续的密码学应用奠定了重要的数学基础。

计算机科学的数学基础:L2.3.3:整数环 Z_n 🔢

在本节课中,我们将学*“整数环 Z_n”这一重要概念。我们将看到如何通过余数算术来构建一个自洽的数学系统,并利用它来更简洁地证明欧拉定理。

概述

上一节我们讨论了同余关系。本节中,我们将引入整数环 Z_n,它将同余算术转化为一个关于“相等”的系统,从而简化推理和证明过程。

从余数算术到整数环 Z_n

谈论同余关系的另一种方式是严格地与余数一起工作。这样做的好处是事情会简单一点,因为你无需担心两个余数的乘积可能太大而超出范围,需要再次取余数来“打回”范围内。

整数环 Z_n 以一种优雅的方式捕捉到了这种模 n 的抽象概念。它允许我们严格地谈论“相等”,而不是“同余”。使用余数算术的基本思想是,每当得到一个太大而不是余数的数字时,我们只需再次应用取余操作,使其回到范围内。

Z_n 中的运算正是这样工作的。Z_n 的元素是余数,即从 0 到 n-1(包含 0,不包含 n)的整数。因此,Z_n 中有 n 个元素:0, 1, 2, ..., n-1。

以下是 Z_n 中运算的定义:

  • 加法(i + j) mod n
  • 乘法(i * j) mod n

这并非一个戏剧性的新想法,但其回报在于让一些事情的表述更容易,因为我们谈论的是相等而非同余。这个由区间 [0, n) 内的整数(方括号 [ 表示包含,圆括号 ) 表示排除)在模 n 加法和乘法下组成的数学结构,称为整数环 Z_n

Z_n 中的算术

Z_n 中的算术本质上就是同余算术,只不过现在使用“等于”而非“同余于”。例如,在 Z_7 中,3 + 6 = 2,因为 (3 + 6) mod 7 = 2。同样,9 * 8 = 11 * 6 在 Z_n 中可能成立,因为两边取模 n 后相等。

整数集合 Z 与环 Z_n 之间的联系可以通过一个称为同态的概念来抽象描述。具体来说,取余数操作 r(k) = k mod n 定义了一个从 Z 到 Z_n 的同态。这意味着:

  • r(i + j) = r(i) + r(j) (在 Z_n 中)
  • r(i * j) = r(i) * r(j) (在 Z_n 中)

同余关系与 Z_n 中等式的关系很简单:i ≡ j (mod n) 当且仅当 r(i) = r(j) 在 Z_n 中。这只是“两数同余当且仅当它们有相同的余数”这一事实的重新表述。

Z_n 的代数性质

有了 Z_n 这个自洽的系统,我们可以讨论它满足的代数规则。这些规则以等式形式成立,并且非常熟悉。

以下是加法满足的一些基本规则:

  • 结合律(i + j) + k = i + (j + k)
  • 单位元:存在元素 0,使得 0 + i = i
  • 逆元:对于每个元素 i,存在一个元素 -i,使得 i + (-i) = 0
  • 交换律i + j = j + i

乘法也满足几乎相同的规则:

  • 结合律(i * j) * k = i * (j * k)
  • 单位元:存在元素 1,使得 1 * i = i
  • 交换律i * j = j * i

一个明显的遗漏是乘法逆元(即对于任意 i,不一定存在 j 使得 i * j = 1)。最后,还有一个连接加法和乘法的规则:

  • 分配律i * (j + k) = i*j + i*k

需要注意的一点是,在 Z_n 中不能随意消去公因子。例如,在 Z_12 中,3 * 2 = 2 * 8(因为 6 mod 12 = 16 mod 12 = 6),但消去公因子 2 会得到错误的结论 3 = 8。这与我们之前关于同余式不能随意消去的结论相对应。

Z_n* 与欧拉定理

当我们可以在 Z_n 中消去一个元素时,这个元素具有特殊的性质。这里有一个标准的缩写:Z_n* 表示 Z_n 中所有与 n 互素的元素组成的集合。

以下是关于 Z_n* 的等价描述:

  1. 元素 iZ_n* 中。
  2. in 互素(即 gcd(i, n) = 1)。
  3. i 在 Z_n 中是可消去的(即若 i*a = i*b,则 a = b)。
  4. i 在 Z_n 中存在乘法逆元(即存在 j 使得 i*j = 1)。

Z_n* 是一个值得关注的坚固子集。我们还知道,欧拉函数 φ(n) 的定义就是区间 [0, n) 内与 n 互素的整数的个数,这正好等于 Z_n* 集合的大小,即 φ(n) = |Z_n*|

现在,我们可以用一种更方便的方式重述欧拉定理,不再提及同余,而是谈论 Z_n 中的等式:

欧拉定理:对于任意属于 Z_n* 的元素 k(即与 n 互素),有 k^(φ(n)) = 1 (在 Z_n 中)。

欧拉定理的证明(基于 Z_n*)

欧拉定理的证明可以从几个简单的观察出发,只需几步即可完成。

引理 1(乘以可逆元保持集合大小):设 S 是 Z_n 的任意子集,k 是 Z_n* 中的任意元素(即可消去/可逆)。令 k * S = {k * s | s ∈ S}。则集合 k * S 与 S 大小相同。
证明思路:因为 k 可消去,所以如果 S 中的 s1 ≠ s2,则 k*s1 ≠ k*s2。因此,乘法操作只是将 S 中的元素一一对应地映射到新集合,没有重合。

引理 2(Z_n 对乘法封闭)*:如果 ij 都属于 Z_n*,那么它们的乘积 i*j 也属于 Z_n*
证明思路:如果 i 和 j 都与 n 没有公因子,那么它们的乘积显然也与 n 没有公因子,因此其模 n 的余数也与 n 互素。

推论:对于任意 k ∈ Z_n*,有 k * Z_n* = Z_n*
证明

  1. 根据引理 2,k * Z_n* 中的每个元素都属于 Z_n*,所以 k * Z_n* ⊆ Z_n*
  2. 根据引理 1,集合 k * Z_n*Z_n* 大小相同 (= φ(n))。
  3. 由于前者是后者的子集且大小相等,所以两者必然相等。

这意味着,用 Z_n* 中的任意元素 k 去乘整个 Z_n* 集合,只是将集合中的元素重新排列(构成一个置换)。

证明欧拉定理

  1. 根据推论,对于 k ∈ Z_n*,有 Z_n* = k * Z_n*
  2. 考虑这两个相等集合中所有元素的乘积:
    • 左边: ∏_{a ∈ Z_n*} a
    • 右边: ∏_{a ∈ Z_n*} (k * a)
  3. 右边的乘积可以改写为:∏_{a ∈ Z_n*} (k * a) = (∏_{a ∈ Z_n*} k) * (∏_{a ∈ Z_n*} a) = k^(φ(n)) * (∏_{a ∈ Z_n*} a)
    (因为共有 φ(n) 个 k 相乘)。
  4. 因此我们得到等式:∏_{a ∈ Z_n*} a = k^(φ(n)) * (∏_{a ∈ Z_n*} a) (在 Z_n 中)。
  5. 注意到 ∏_{a ∈ Z_n*} aZ_n* 中元素的乘积,根据引理 2,这个乘积本身也属于 Z_n*,因此它是可消去的
  6. 在等式两边消去 ∏_{a ∈ Z_n*} a,即得:1 = k^(φ(n)) (在 Z_n 中)。

证毕。

总结

本节课中,我们一起学*了整数环 Z_n 的概念。我们了解到 Z_n 通过取余运算将模 n 同余算术转化为一个关于相等的代数系统,从而简化了表述和证明。我们探讨了 Z_n 的基本代数性质,并重点介绍了其中可逆元素组成的子集 Z_n。最后,我们利用 Z_n 的性质,特别是“用可逆元相乘相当于重排集合”这一关键引理,给出了欧拉定理一个简洁而优雅的证明。这个证明展示了将数论问题置于适当的代数结构中进行思考的威力。

计算机科学的数学基础:L2.4.1:RSA公钥加密 🔐

在本节课中,我们将要学*RSA公钥加密系统。这是一个将数论应用于计算机科学的重要实例,它允许任何人仅使用公开信息向指定接收者发送加密的私密消息。

概述

RSA是一种公钥加密系统,它拥有一个惊人的特性:任何人无需事先联系,仅使用公开可用的信息,就能向指定接收者发送加密的私密消息。这意味着你可以向亚马逊发送一条只有亚马逊能读的消息,即使全世界都知道你发送了什么。这听起来有些矛盾,但它的存在确实带来了一些令人费解的后果。

上一节我们介绍了数论的基础概念,本节中我们来看看如何利用这些概念构建一个实用的加密系统。

公钥加密的“悖论”

公钥加密系统的存在似乎违背直觉。一个经典的类比是“脑力扑克”。想象一下,两个人不借助任何实体工具,仅通过对话就能玩一局公*的扑克牌。这听起来不可能,但利用公钥加密技术,这实际上是可行的。Rivest和Shamir的一篇著名论文就阐述了如何实现“脑力扑克”。

其核心思想在于单向函数的存在。单向函数是指正向计算容易,但逆向求解极其困难的函数。一个关键的洞察是:知道如何计算一个函数,并不代表能轻易地找到它的逆。

RSA的工作原理

现在,让我们具体看看RSA协议是如何工作的。整个过程涉及两个角色:接收者(准备接收加密消息)和发送者(发送加密消息)。

接收者的准备工作

接收者需要先生成并公布其公钥,同时秘密保存私钥。以下是具体步骤:

以下是接收者生成密钥对的步骤:

  1. 生成两个大素数:随机选择两个大素数 PQ。在实际应用中,它们通常有数百位长。
  2. 计算模数 N:计算 N = P * Q。这个 N 将成为公钥的一部分。
  3. 选择加密指数 e:选择一个整数 e,使得 e(P-1)*(Q-1) 互质(即最大公约数为1)。这个 e 也将成为公钥的一部分。
  4. 计算解密指数 d:计算 e 在模 (P-1)*(Q-1) 下的乘法逆元 d。即找到 d 使得 e * d ≡ 1 (mod (P-1)*(Q-1))。这个 d 就是私钥,必须严格保密。

最终,接收者将 (e, N) 作为公钥公开,而将 (d, P, Q) 作为私钥秘密保存。

发送者的加密过程

当发送者想发送一条消息 M 给接收者时,他需要执行以下操作:

以下是发送者加密消息的步骤:

  1. 获取公钥:从公开目录中获取接收者的公钥 (e, N)
  2. 准备消息:将消息 M 转换为一个小于 N 的整数。如果消息很长,可以将其分割成多个块。
  3. 加密计算:在模 N 的算术下,计算密文 CC ≡ M^e (mod N)
  4. 发送密文:将计算得到的密文 C 发送给接收者。

接收者的解密过程

接收者收到密文 C 后,使用自己的私钥进行解密:

接收者只需在模 N 的算术下,计算 C^d (mod N)。根据欧拉定理(当 MN 互质时)以及更一般的理论,这个计算结果恰好等于原始消息 M。这样,接收者就成功解密了消息。

可行性分析

为了使RSA系统可行,各方必须能够高效地执行其任务。让我们逐一分析。

接收者的任务

接收者需要完成几项关键操作:

以下是接收者需要高效完成的任务:

  • 寻找大素数:根据素数定理,在 n 位数中,大约每 log n 个数中就有一个素数。因此,随机测试几百个数字就很可能找到一个素数。关键在于如何快速测试一个数是否为素数。
  • 测试素数:一个实用且高效的方法是费马素性测试。其原理基于费马小定理:如果 n 是素数,那么对于任意与 n 互质的整数 a,有 a^(n-1) ≡ 1 (mod n)。如果这个等式对某个随机选择的 a 不成立,则 n 一定是合数。如果成立,则 n 很可能是素数。通过多次随机选择 a 进行测试,可以将误判概率降到极低。
  • 寻找互质的 e:随机选择一个中等大小的 e,并使用欧几里得算法检查其是否与 (P-1)*(Q-1) 互质。由于互质的数很常见,通常很快就能找到合适的 e
  • 计算逆元 d:使用扩展欧几里得算法(辗转相除法)可以高效地计算出 d

系统的安全性

RSA的安全性基于一个公认的数学难题:大整数分解的困难性

  • 攻击方式:如果攻击者能够将公开的 N 分解为 PQ,那么他就能轻易计算出 (P-1)*(Q-1),进而利用公钥 e 计算出私钥 d,从而破解整个系统。
  • 安全信念:目前,没有已知的算法能在多项式时间内分解大整数的乘积。尽管这在理论上(与P vs NP问题相关)尚未被证明,但经过数十年的研究和最强大的计算资源的攻击,RSA算法(在正确实施参数的情况下)依然保持稳固。整个金融、政府和商业世界都将安全赌注压在了分解大整数的难度之上。
  • 安全性证明:可以证明,如果攻击者能够获取私钥 d,那么他也能分解 N。因此,在“分解是困难的”这一前提下,获取私钥也是困难的。不过,最强的安全性定理——即“任何破解RSA的方法都等价于分解 N”——仍然是一个开放问题。

总结

本节课中我们一起学*了RSA公钥加密系统。我们从其看似“悖论”的特性讲起,理解了单向函数的核心概念。随后,我们详细拆解了RSA的三个核心流程:接收者的密钥生成、发送者的消息加密以及接收者的消息解密。最后,我们分析了该系统的可行性,包括如何高效寻找大素数,并深入探讨了其安全性的基石——大整数分解问题的计算困难性。尽管存在更强的安全性证明这一开放问题,但RSA凭借其数十年来经受住的实践考验,已成为现代安全通信不可或缺的基石之一。

计算机科学的数学基础:L2.4.3:将因数分解归约到SAT问题 🔧

在本节课中,我们将学*如何将因数分解问题归约到命题逻辑的可满足性问题。我们将看到,如果能高效地解决SAT问题,就能高效地进行因数分解。这解释了为什么SAT问题在理论计算机科学中占据核心地位。

概述

我们曾多次提及P与NP问题,这是理论计算机科学中最重要的问题之一。该问题的一种表述方式是:是否存在一种高效的多项式时间算法,能够判断一个命题逻辑公式是否可满足。为什么这个问题如此重要?我们不仅仅是逻辑学家,关心公式是否可满足。SAT问题之所以具有巨大重要性并应用于众多领域,是因为许多问题都可以归约到它。通过展示如何利用SAT求解器进行高效因数分解,我们可以理解为什么众多问题都能归约到SAT,以及它为何如此核心。

构建乘法电路

假设我们有一个SAT求解器,并想用它来分解一个数字N。首先,我们需要理解如何使用SAT求解器。我们可以设计一个执行算术乘法的数字电路。这个电路有K位输入X,K位输入Y,以及2K位输出,用于表示X乘以Y的结果。这是一个乘法器电路。

乘法器电路:输入K位的X和K位的Y,输出2K位的乘积。这个电路的规模不大,其门和线的数量大约是K的二次方。具体来说,其规模可以限制在5 * K^2 + 常数以内。因此,给定位数K,我们可以轻松构建这个乘法器电路。

结合等式测试器

现在,假设我们有一个测试电路可满足性的方法。如何利用这个乘法器电路进行因数分解呢?首先,假设我们要分解的数字N是两个素数P和Q的乘积,这正是RSA加密中使用的N。

接下来,我们可以设计一个等式测试器。这是一个小型数字电路,它有2K个输入线,当输入是数字N的二进制表示时,其唯一的输出线会输出1。

等式测试器:输入2K位,当且仅当输入等于N的二进制表示时,输出为1。这也是一个容易构建的电路。

现在,我们将乘法器电路和等式测试器连接起来。乘法器的输出(2K位)作为等式测试器的输入。这样,整个组合电路在输出为1时,意味着存在两个K位数X和Y,使得X * Y = N

利用SAT求解器寻找因数

现在,我们固定组合电路的第一个输入位(例如,设为0),然后询问SAT求解器:是否存在一种方式设置剩余的输入位,使得电路的最终输出为1?如果SAT求解器回答“是”,则意味着存在一个因数(X或Y)以0开头。

接着,我们尝试将第二个输入位也设为0,并再次询问SAT求解器。如果这次回答“否”,则意味着第二个输入位必须为1,才能存在满足X * Y = N的因数对。

我们重复这个过程,对每一位进行测试。对于第i位,我们将其设为0,然后询问SAT求解器电路是否可满足(即输出能否为1)。根据回答,我们可以确定该位是0还是1。

过程总结:通过最多进行2K次SAT测试(因为X和Y各有K位),我们可以逐位确定X和Y的值,从而找到N的因数P和Q。如果每次SAT测试的时间复杂度是K的多项式,那么整个因数分解过程的时间复杂度也是K的多项式。

从电路到命题公式

我们之前将SAT问题定义为关于命题逻辑公式的问题:给定一个公式,判断它是否可满足。然而,我们刚才讨论的是电路的满足性。如何将两者联系起来呢?

我们可以为电路中的每一条线分配一个新的命题变量。然后,为电路中的每一个逻辑门(如与门、或门、非门)编写一个小公式,描述该门的输入线和输出线之间的关系。这个小公式编码了该门的逻辑功能。

公式构建:将所有门对应的小公式进行逻辑与(AND)操作,就得到了一个描述整个电路结构的命题逻辑公式。这个公式是可满足的,当且仅当原始电路能够输出1。

因此,如果我们假设能够高效测试公式的可满足性,那么我们就能高效测试电路的可满足性,进而就能高效进行因数分解。这是一个简单的技巧,可以找到一个与电路规模大致相同的命题公式,其可满足性与电路能否输出1等价。

总结

本节课中,我们一起学*了如何将因数分解问题归约到命题逻辑的可满足性问题。我们首先构建了一个乘法器电路和一个等式测试器,并将它们组合。然后,我们展示了如何通过逐位询问SAT求解器,来确定构成乘积N的两个因数。最后,我们解释了如何将任何数字电路转化为一个等价的命题逻辑公式,从而将电路的可满足性问题归约到公式的SAT问题。这个归约过程清晰地展示了SAT问题的核心地位:如果能高效解决SAT,就能高效解决包括因数分解在内的许多重要计算问题。

计算机科学的数学基础:L2.5.1:有向图 - 行走与路径 🧭

在本节课中,我们将要学*有向图的基本概念,包括其定义、表示方法,以及如何描述图中的行走与路径。


有向图简介

在之前的课程中,你可能认为“图”是类似 Y = f(X) 在XY*面上的图像。但这不是我们所要讨论的。计算机科学中的图,是由一系列顶点和连接顶点的边构成的。

更具体地说,一个有向图包含一个顶点集合 V 和一个边集合 E。每条边由两个顶点组成,写作 (v, w),表示一条从顶点 v 指向顶点 w 的边。在图中,它看起来是这样的:

需要注意的是,边是有方向的。从 vw 的边与从 wv 的边是不同的。例如,上图就是一个有向图。你可以将顶点集合 V 写为图中所有顶点的集合,而边集合 E 则是顶点对的集合。

同时,有向图等价于顶点集合 V 上的一个二元关系。因为每条边都定义了一个顶点到另一个顶点的关系。因此,任何二元关系都可以绘制成一个有向图:将集合中的每个元素作为顶点,并用边表示从一个元素到另一个元素的关系。


行走与路径

上一节我们介绍了有向图的基本结构,本节中我们来看看如何在图中移动,即“行走”与“路径”的概念。

一个“行走”是指沿着连续的边前进,它可以重复经过顶点或边。例如,从图中的黑色顶点出发,可以走到红色、蓝色、黄色、红色,然后再回到蓝色。这没有任何限制。

行走的长度不是经过的顶点数,而是经过的边数。在上面的例子中,长度是5(黑→红→蓝→黄→红→蓝),而不是经过的6个顶点。需要注意这个“差一”的区别。

另一方面,“路径”是一种特殊的行走,它不允许重复经过任何一个顶点。例如,从蓝色顶点出发,可以走到黄色、红色、粉色、绿色,然后就无法继续了,因为不能再回到已经访问过的红色顶点。这就是一条路径的终点。这条路径的长度是4(蓝→黄→红→粉→绿),对应5个顶点。


图的矩阵表示

每个有向图都可以用一个矩阵来表示,这种表示法称为邻接矩阵。

以下是构建邻接矩阵的方法:我们画一个矩阵,行和列都对应图中的顶点。如果存在一条从行顶点指向列顶点的边,我们就在该位置填入 1;否则填入 0

例如,如果存在一条从黑色顶点到红色顶点的边,就在黑色行、红色列的位置填入 1。同样,如果存在从黑色到绿色的边,就在黑色行、绿色列填入 1,以此类推,为图中所有边进行标记。其余位置则用 0 填充。

如上图所示,这个矩阵唯一地定义了一个图。每条边都在矩阵中有所体现,每个顶点也都有对应的行和列。因此,任何有向图都可以用这样一个邻接矩阵来完整描述。


总结

本节课中我们一起学*了有向图的核心概念。我们首先定义了有向图,它由顶点集和边集构成,并且边具有方向。接着,我们区分了“行走”和“路径”:“行走”允许重复顶点和边,而“路径”则不允许重复顶点。最后,我们介绍了如何使用邻接矩阵来清晰地表示一个有向图的结构,其中矩阵的行和列对应顶点,矩阵中的 10 表示边是否存在。

计算机科学的数学基础:L2.5.3:有向图 - 连接的顶点 🔗

在本节课中,我们将学*有向图中顶点之间的连接性。我们将探讨如何定义和计算顶点间的“游动”关系,并理解最短游动与路径之间的关系,以及如何高效地计算这些连接。


上一节我们介绍了有向图的基本概念,本节中我们来看看顶点之间如何通过边建立连接。

最短游动与路径 🛤️

首先,我们将证明:两个顶点之间的最短游动必然是一条路径。我们将使用反证法来证明这一点。

假设存在一条从顶点 u 到顶点 v 的游动,但它并非一条路径,这意味着它在某个顶点 c 处穿过了自身。即,游动从 u 出发,到达 c,之后又再次回到 c,最后才到达 v

如果你想找到从 uv 的最短路径,那么为什么要经历这个循环呢?为什么不直接从 c 走到 v?因此,从 c 回到自身的这段游动是冗余的。如果我们去掉这个绕回来的部分,我们仍然有一条从 uv 的游动,并且它更短。

因此,从 uv 的最短游动必然是一条路径。


理解了最短游动后,我们来正式定义顶点间的连接关系。

长度 n 的游动关系 🧮

我们定义 Gⁿ 关系:对于图 G 中的两个顶点 vw,如果存在一条从 vw 的长度为 n 的游动,则称 vw 具有 Gⁿ 关系。Gⁿ 被称为图 G长度为 n 的游动关系

本质上,如果你能在 n 步内从 v 走到 w,那么 Gⁿ 关系就适用于 vw

n=1 时, 就是图 G 本身的邻接关系,即如果两个顶点之间有一条边,则它们具有 关系。


现在,我们来看一个关于这些关系组合的重要引理。

关系组合引理 🔗

引理指出:GᵐGⁿ 的关系组合等于 Gᵐ⁺ⁿ 关系。用公式表示如下:

Gᵐ ∘ Gⁿ = Gᵐ⁺ⁿ

让我们解释一下这意味着什么。关系组合 Gᵐ ∘ Gⁿxy 成立,当且仅当存在某个顶点 z,使得有一条从 xz 的长度为 m 的游动(即 Gᵐ 关系),以及一条从 zy 的长度为 n 的游动(即 Gⁿ 关系)。

这与 Gᵐ⁺ⁿ 的定义是一致的:从 x 出发,走 m 步到 z,再走 n 步到 y,总共就是一条从 xy 的长度为 m+n 的游动。

长度为零的游动关系 G⁰ 是自反关系,它使每个顶点指向自身。引理在这种情况下依然成立,例如 G⁰ ∘ Gⁿ = Gⁿ


为了计算这些关系,我们需要将其与矩阵运算联系起来。

矩阵表示与布尔运算 🧮

如果我们用邻接矩阵 A 来表示图 G,那么关系 GᵐGⁿ 的组合可以通过矩阵的 布尔乘法 来计算。

布尔乘法与普通矩阵乘法类似,但将加法替换为逻辑“或”(∨),将乘法替换为逻辑“与”(∧)。因此,Gᵐ⁺ⁿ 对应的矩阵可以通过计算 A(m+n) 次布尔幂来获得。


有了矩阵表示,我们可以高效地计算高次幂。

快速矩阵幂运算 ⚡

我们可以使用快速幂算法来计算 Aⁿ(即 Gⁿ 的矩阵表示)。基本思想是:

Aⁿ = (A^(n/2))² (当 n 为偶数时)

通过不断将指数减半并*方结果,我们可以在 O(log n) 次矩阵乘法内计算出 Aⁿ,这比连续乘 n 次要高效得多。


最后,我们定义图中最重要的连接关系。

游动闭包关系(G*) 🌟

我们定义 G* 关系,称为图 G游动关系可达关系。对于顶点 uv,如果存在 任意长度 的从 uv 的游动(即它们是连通的),则 uv 具有 G* 关系。

u G* v ⇔ ∃k ≥ 0, u Gᵏ v

如何计算 G* 呢?考虑一个具有 n 个顶点的图。任何路径的长度最多为 n-1(因为穿过所有 n 个顶点最多需要 n-1 条边)。因此,如果我们考虑图 G≤,它是在原图 G 的基础上,为每个顶点添加一条指向自身的边(即包含 G⁰ 关系),那么:

G* = (G≤)ⁿ⁻¹

这意味着,要得到所有顶点对之间的可达性,我们只需要计算 G≤(n-1) 次布尔幂。这可以通过矩阵运算在 O(n³) 时间内完成(或者使用更高效的算法)。


以下是本讲核心概念总结:

  • 最短游动即路径:两个顶点间的最短游动不会包含循环,因此是一条路径。
  • Gⁿ 关系:表示长度为 n 的游动可达性。
  • 关系组合Gᵐ ∘ Gⁿ = Gᵐ⁺ⁿ,可通过布尔矩阵乘法计算。
  • 快速幂算法:可高效计算 Aⁿ,时间复杂度为 O(log n) 次矩阵乘法。
  • 游动闭包 G*:表示所有可能的游动连接(即可达性),可通过计算 (G≤)ⁿ⁻¹ 获得。

本节课中我们一起学*了有向图中顶点连接性的形式化定义与计算方法。我们证明了最短连接即是路径,引入了基于游动长度的关系 Gⁿ 及其组合性质,并展示了如何用邻接矩阵和布尔运算来高效计算这些关系,最终定义了表示全局连通性的游动闭包 G*。这些概念是分析图算法和网络结构的基础。

计算机科学的数学基础:L2.6.1:有向无环图 (DAGs) 📊

在本节课中,我们将学*一种特殊的图——有向无环图。这种图在计算机科学和许多其他领域中都非常重要,例如课程先修关系、任务调度等。我们将了解它的定义、特性以及如何找到其最简洁的表示形式。


什么是 DAG?

有向无环图是一类特殊的图。顾名思义,它是有向的,并且不包含任何环。由于“有向无环图”这个词组较长,通常简称为 DAG

这类图之所以无处不在,是因为它能很好地表示具有先后依赖关系的事物。让我们看一个熟悉的例子。


一个典型例子:课程先修图

下图展示了麻省理工学院电气工程与计算机科学系 6-3 项目中必修课程的先修结构。其他专业或院系也有类似的图表。

这个图是什么意思呢?让我们看顶点 1801(第一学期的微积分课程)。有一条边指向 6042。这是因为在课程目录中,60421801 列为其先修课程。

如果我们看算法入门课 6006,目录中列出了两个先修课:6042601。正因为目录中明确列出了这些先修关系,所以图中存在从 6016042 指向 6006 的箭头。

如果你想上 6006,你不仅需要先上 6042601,还需要上这些先修课的先修课。因此,在上 6006 之前,你必须先上 180182。图中还有一些“共同先修”关系,我们暂时忽略它们,将其视为先修关系,以免分散注意力。

这个图表就是一个 DAG。它由一系列顶点(课程标签)和表示目录中先修关系的箭头组成。


间接先修关系与可达性

在规划课程时,你真正关心的是间接先修关系。一门课程 u 是另一门课程 v 的间接先修课,意味着存在一个从 uv 的先修序列。这意味着你必须在某个时间点上过 u 之后才能上 v,这是在规划课程表时需要考虑的关键事实。

用有向图的语言来说,uv 的间接先修课,意味着在表示先修关系的有向图 D 中,存在一条从 uv正长度通路

因此,我们关心的是有向图 D正长度通路关系,记作 D+u D+ v 表示存在一条从 uv 的正长度通路。


为什么不能有环?

现在,考虑一个闭通路,即起点和终点是同一个顶点的通路。假设存在一条从 6042 开始并结束于 6042 的闭通路,那么需要多久才能毕业呢?

答案是:永远不能。因为你无法在上 6042 之前先上完 6042。这显然是个问题。我们绝对不希望院系的课程先修结构中存在正长度的闭通路。

事实上,通常有专门的委员会来检查这类问题。在规划包含数十甚至上百门课程的复杂项目时,偶尔会出现这种错误。委员会的工作就是确保提议的课程要求满足规则。

闭通路的一个特例是。环是一条通路,其中除了起点和终点是同一个顶点外,没有其他重复顶点。

需要说明的是,单个顶点本身构成一个长度为 0 的环。我们无法消除长度为 0 的环,因为它们就是顶点本身。但我们希望确保没有正长度的环。

如果要用路径表示一个环,可以展示顶点和边的序列 v0, v1, v2, ..., vn,其中从 v0vn-1 的所有顶点都互不相同,而最后一个顶点 vn 等于 v0,这是环中唯一允许的重复。我们可以将其画成一个圆圈。

关于环和闭通路,有一个简单的引理:从一个顶点到其自身的、最短的正长度闭通路,就是一个以该顶点为起点和终点的正长度环。证明思路与“两点间最短通路是路径”的证明类似:如果一个闭通路中存在除起点外的重复顶点,就可以剪掉重复部分之间的路径,从而得到一个更短的闭通路。因此,最短的闭通路不能有任何重复,它必须是一个正长度的环。


DAG 的正式定义

基于以上讨论,有向无环图 正式定义为:不包含任何正长度环的有向图

由于环是闭通路的特例,我们也可以等价地定义为:不包含任何正长度闭通路的有向图


DAG 的其他例子

DAG 的例子有很多:

  1. 课程先修图:如上所述。
  2. 任务约束图:任何描述任务间“必须先于”关系的集合,都会定义一个 DAG 结构。
  3. 后继关系图:考虑整数集上的后继关系,从 nn+1 有一条有向边。这个图的通路关系恰好表示了“小于”关系(n < m)。由于“小于”关系不具有对称性(如果 a < b,则不可能有 b < a),所以这个图中不可能有环,因此它是一个 DAG。
  4. 真子集关系图:在集合之间,如果集合 A 是集合 B 的真子集(A ⊂ BA ≠ B),则从 AB 画一条有向边。同样,因为一个集合不可能是其自身的真子集,所以这个图中也不可能有环,它也是一个 DAG。

从这些例子中,希望你能开始理解为什么 DAG 在数学和其他领域如此普遍和重要。


DAG 的最小表示:覆盖边

当我们研究一个 DAG 时,通常只关心它的通路关系。如果两个 DAG 具有相同的通路关系,那么它们是等价的。很自然地,我们会问:对于一个给定的通路关系,是否存在一个最精简(边数最少)的 DAG 来表示它?

让我们看一个例子。下图是一个简单的 DAG,你可以验证它没有环。

与这个 DAG 具有相同通路关系的最小 DAG 是什么?我们可以通过逐一检查每条边来找到它,判断是否可以删除某条边而不影响顶点间的可达性。

  • 观察路径 A -> B -> E。这条路径的存在意味着直接从 AE 的边对于连通性没有贡献,因为总可以通过 BA 走到 E。因此,可以删除边 A->E
  • 观察路径 A -> C -> D。同样,可以直接删除边 A->D,因为可以通过 C 到达。
  • 观察路径 C -> D -> F。可以删除边 C->F
  • 观察路径 A -> C -> D -> F。可以删除边 A->F
  • 观察路径 B -> D -> F。可以删除边 B->F

经过这些删除操作后,剩下的边被称为覆盖边。覆盖边的特性是:如果删除一条覆盖边 u->v,那么从 uv 将不再可达。换句话说,从 uv 的唯一直接方式就是通过这条覆盖边(虽然可能还有其他更长路径,但这条边是关键的直接连接)。

如果存在其他不经过边 u->v 就能从 u 到达 v 的路径,那么 u->v 就不是覆盖边。覆盖边是定义通路关系所必需的最小边集,所有其他边都是冗余的。


总结

本节课中,我们一起学*了有向无环图

  1. 我们首先通过课程先修图的例子,直观理解了 DAG 如何表示依赖关系。
  2. 然后,我们定义了间接先修关系,对应于图中的正长度通路关系 (D+)
  3. 我们探讨了为什么 DAG 中不能有正长度闭通路,并用“最短闭通路是环”的引理进行了说明。
  4. 接着,我们给出了 DAG 的正式定义,并列举了包括后继关系真子集关系在内的其他例子。
  5. 最后,我们讨论了如何寻找 DAG 的最小表示,即通过识别和保留覆盖边,删除所有冗余边,而不改变顶点间的可达性。

DAG 是计算机科学中表示层次结构、依赖关系和偏序的强大工具,理解其基本概念对后续学*至关重要。

计算机科学的数学基础:L2.6.3:调度问题详解 📅

在本节课中,我们将要学*如何利用有向无环图(DAG)来表示和解决课程调度问题。我们将从理解先决条件图开始,逐步介绍极小元素、反链、链等核心概念,并最终学*如何制定一个可行的课程学*计划。


图表示与间接先决条件

在上一节中,我们了解到用图表表示课程之间的调度约束非常关键,并且那张图表实际上是一个有向无环图(DAG)

现在让我们更详细地看看这个由DAG表示的调度问题。下图展示了一个课程选择的图表,其中包含了六个先决条件。虽然有些信息可能已经过时,但它作为一个说明性的例子非常有用。图中的小箭头指示了课程之间的直接先决关系。

例如,箭头告诉我们 18.016.042 的直接先决条件。同时,18.01 也是 18.02 的直接先决条件。此外,6.0016.004 都是 6.003 的先决条件。

这里我们遇到了之前提到的间接先决条件问题。尽管课程目录中只列出 6.0466.840 的先决条件,但实际上,要学* 6.046,你必须先学* 6.042。因此,6.0426.840 的间接先决条件。

用图论的语言来描述:科目 u 是科目 v 的间接先决条件,当且仅当在描述课程先决条件结构的图中,存在一条从 uv正长度路径

使用关系符号表示,设 R 为有向图中的直接先决关系,R+ 表示其传递闭包(即正长度路径关系)。那么 u R+ v 就读作“存在一条从 uv 的正长度路径”。


极小元素与贪婪策略 🎯

接下来,我们将研究一个关键概念:极小元素

极小元素的定义是:一个没有先决条件的科目。在图中,这意味着没有箭头指向它。在前面的图表中,极小元素是 18.018.026.001

“极小”这个术语来源于偏序理论。在DAG所表示的偏序关系中,我们可以认为后面的科目“大于”前面的科目。因此,一个极小科目就是一个没有比它“更小”的科目。图中可能存在多个极小元素,因为它们彼此之间没有先后关系。

现在,我们可以讨论如何进行调度。我们要做的第一件事就是识别出所有的极小元素。在上例中,我们识别出了三个。

我们将采用一种贪婪策略:在任何学期,只要条件允许,就尽可能多地学*课程。因此,我们可以在第一学期选修所有新生课程(即极小元素),因为它们没有先决条件。

安排完这些课程后,我们就可以将它们从考虑中移除,因为它们已经“完成”了。这不仅移除了这些课程本身,也移除了所有以它们为先决条件的事件(箭头)。这样,我们就得到了一个简化后的新图。


层级调度与反链

在简化后的新图中,一些原本不是极小的元素现在变成了新的极小元素。这些就是“第二级”的极小元素。

以下是识别出的第二级极小元素列表:

  • 6.042
  • 18.02
  • 6.002
  • 6.004
  • 6.003

我们接下来安排这些课程。它们构成了我们第二学期可以学*的科目集合。同样地,在移除这些第二级课程后,我们会发现 6.0466.020 变成了新的极小元素,可以将它们安排在第三学期。以此类推,我们可以得到完整的学期安排。

当然,存在许多其他的安排方法,但这里描述的是一种特别有序的贪婪策略。

在讨论调度时,值得引入反链这个概念。在这个例子中,一个反链指的是一组彼此之间没有间接先决条件关系的科目。这意味着它们可以以任何顺序学*,因为学*其中一门并不依赖于学*组内的其他科目。

用技术语言描述:如果两个元素 uv 之间既没有从 uv 的正长度路径,也没有从 vu 的正长度路径,则称它们是不可比的。一个反链就是一组两两不可比的元素。

让我们看一些反链的例子。我们每个学期安排的课程集合就是一个反链。例如,第一学期的新生课程之间没有路径,所以它们构成一个反链。第二学期安排的“第二级极小元素”之间也没有路径,是另一个反链。

但并非所有的反链都出现在我们的时间表中。例如,6.8406.0206.034 之间没有路径,因此它们也构成一个反链。这意味着在满足它们所有先决条件(位于图左上角)后,有可能在同一学期学*这三门课。


链、拓扑排序与最短毕业时间 ⏱️

现在,让我们探讨各种可能的调度模式。我们发现了上述绿色的贪婪调度方案。但假设我每学期只想选一门课。我能做到吗?

答案是肯定的。只要首先按任意顺序安排所有极小元素(每学期一门),然后安排所有第二级极小元素,以此类推。这完全是可行的。这种为DAG中所有节点生成一个线性顺序(使得所有边都从前指向后)的过程,称为拓扑排序

“排序”一词源于将路径关系视为一种“小于或等于”的关系。因此,我们按照这种“大小”顺序来排列事物。

与反链相对的概念是。链是一系列必须按特定顺序进行的科目。对于链中的任何两个科目,你都知道哪个必须先学。这意味着在链中,任意两个元素之间都存在一条路径(从一个到另一个)。

例如,图中存在一条包含五门课程的垂直链。这里也有一条长度为四的垂直链。并非所有链都是垂直的。例如,你必须先学 18.01,然后学 18.03,最后才能学 6.004,它们也形成了一条链。

重要的是,一条链不一定包含所有可能的元素。即使只包含 8.02 -> 6.020 -> 6.857 这三个科目,它仍然是一条链,因为存在从 8.026.020 以及从 6.0206.857 的路径。

最大长度链(即尽可能长的链)在理论上很重要。图中存在一条长度为5的最大链(它不唯一)。这就引出了一个关键问题:毕业最少需要多少个学期?

我们看到,你可以在五个学期内毕业。但考虑到存在一条最大长度为5的链,这意味着你不可能用更少的时间毕业,因为这五门课必须连续学*,每一门都必须在上一门被选修后的学期才能选修。

定理:毕业所需的学期数至少要和图中最大链的长度一样大。
因此,五个学期是必要的。而通过我们的贪婪极小策略,我们证明了五个学期也是足够的(假设每学期可以选修不限数量的课程)。


负载均衡与调整

当然,一个结果是,在我大一的第二学期,我可能需要上五门课(因为贪婪策略允许这样做)。但这可能导致学期负载不均衡,例如最后一个学期可能只有一门课。

实际上,我们可以调整时间表来实现负载均衡。例如,完全可以将 18.02 从第二学期移到第三学期,因为它在第一学期后就已经满足了所有先决条件。这样做可以将第二学期的负担减轻到四门课,同时将第三学期的课程增加到三门。

通过进一步调整,你甚至可以找到一个每学期最多只选三门课的毕业时间表。


总结 📝

本节课中,我们一起学*了如何利用DAG来建模和解决课程调度问题。我们定义了极小元素,并介绍了通过贪婪策略进行层级调度的过程。我们学*了反链(可并行学*的课程组)和(必须顺序学*的课程序列)的概念,并理解了最大链的长度决定了毕业所需的最小学期数。最后,我们还探讨了在满足先决条件的前提下,如何调整时间表以实现学期间的负载均衡。掌握这些概念,是理解和设计高效调度方案的基础。

计算机科学的数学基础:L2.6.5:时间与处理器 ⏱️💻

在本节课中,我们将学*任务调度中的一个核心问题:在存在先后依赖关系(即部分任务必须按顺序执行,部分可以并行执行)的情况下,如何确定完成任务所需的最短时间以及所需的最少处理器数量。我们将通过课程安排的例子引入关键概念,并探讨一个有趣的数学引理及其应用。

概述 📋

任务调度是计算机科学和许多其他领域的常见问题。我们经常面临一组任务,其中一些任务必须在其他任务完成后才能开始。如果允许并行处理,我们关心两个核心指标:完成所有任务所需的最短时间,以及为实现这个最短时间所需的最少处理器数量。本节将形式化这些问题,并利用有向无环图(DAG)的理论给出答案。

最短并行时间与最大链 ⛓️

上一节我们介绍了课程安排的例子,它是一般任务调度问题的特例。在这个问题中,任务间的依赖关系构成了一个约束图(通常是一个DAG)。

我们能对一组有约束的任务说些什么呢?假设并行处理能力不受限制(即可以使用任意多的处理器同时工作),那么完成所有任务所需的最短时间,简单地等于约束图中最大链的大小。

  • :在DAG中,一条链是一系列顶点,其中每个顶点都有一条边指向链中的下一个顶点。这代表了一系列必须严格按顺序执行的任务。
  • 最大链:图中所有链中包含顶点最多的那条链。它代表了整个任务流程中无法被并行的、最长的关键路径。

公式最短并行时间 = 最大链尺寸

在课程安排的例子中,最大链尺寸为5,这意味着学生至少需要5个学期才能毕业。

所需处理器数量与最大反链 🔗

接下来,我们看看为实现这个最短时间,需要多少个处理器(或在课程例子中,一个学期最多需要修多少门课)。这与图中最大反链的尺寸有关。

  • 反链:在DAG中,一个反链是一组顶点,其中任意两个顶点之间都没有路径相连(即它们互相不可比)。这代表了一组可以完全并行执行的任务。
  • 最大反链:图中所有反链中包含顶点最多的那个反链。它代表了理论上可以同时进行的最大任务量。

公式所需处理器数 ≤ 最大反链尺寸

在课程例子中,最大反链尺寸是5。但这只是一个上限。实际上,我们可能不需要那么多处理器就能在最短时间内完成任务。例如,在之前的课程安排中,我们实际上只需要每学期安排3门课(即3个“处理器”),就能在5个学期内完成所有13门课。

迪尔沃斯引理及其含义 🧮

那么,我们能否做得比3门课/学期更好呢?一个简单的论证表明不能。我们有13门课(n=13),最大链尺寸为5(c=5)。要在5个学期内分配13门课,根据鸽巢原理,至少有一个学期需要安排 ceil(13/5) = 3 门课。这是一个普遍现象。

更一般地,对于一个有 n 个顶点的DAG,设其最大链尺寸为 c,最大反链尺寸为 a。那么顶点总数 n 最多为 c * a

公式n ≤ c * a

这个关系可以重新表述为著名的迪尔沃斯引理(Dilworth‘s Lemma)的一个特例:

对于一个有 n 个顶点的DAG和任意数 t(1 ≤ t ≤ n),该图要么包含一个尺寸大于 t 的链,要么包含一个尺寸至少为 n/t 的反链。

公式存在链尺寸 > t 存在反链尺寸 ≥ n/t

一个有趣的应用:身高与年龄的例子 👥

让我们看一个迪尔沃斯引理的简单应用。假设我们有一个班级,有141名学生。我们为每名学生记录身高(精确到微米)和年龄(精确到微秒),以确保没有完全相同的两人。

我们构造一个DAG:如果学生A的身高和年龄都小于等于学生B,则从A到B画一条有向边。这个图是“身高DAG”和“年龄DAG”的乘积图。

根据迪尔沃斯引理,取 t = sqrt(141) ≈ 12,我们可以得出结论:在这个有141个顶点的乘积DAG中,要么存在一个至少包含12人的链,要么存在一个至少包含12人的反链

  • 的含义:如果存在一个12人的链,意味着我们可以找到12名学生,他们随着身高的增加,年龄也增加(或不变)。
  • 反链的含义:如果存在一个12人的反链,意味着我们可以找到12名学生,当他们按身高从高到矮排列时,他们的年龄会随之增加(因为反链中任意两人不可比,所以更矮的人必须更老,否则就会产生可比性)。

在实际的课堂数据中,我们恰好发现了一个包含12名学生的反链:当按身高从高到矮排列时,他们的出生日期确实越来越早(即年龄越来越大)。这验证了迪尔沃斯引理的结论。

总结 🎯

本节课我们一起学*了任务调度中的核心概念:

  1. 最短并行时间由约束图中的最大链尺寸决定。
  2. 所需处理器数量的上限最大反链尺寸决定,但实际所需可能更少。
  3. 链与反链的尺寸受迪尔沃斯引理约束,该引理揭示了它们与任务总数 n 之间的基本关系:n ≤ c * a
  4. 我们通过一个身高-年龄的乘积DAG例子,看到了迪尔沃斯引理的一个具体应用,它保证了在一个足够大的集合中,总能找到一定规模的链或反链。

这些概念不仅适用于课程安排,也广泛适用于项目管理、并行计算以及任何需要处理依赖关系的调度场景。

计算机科学的数学基础:L2.7.1:偏序关系 📚

在本节课中,我们将学*偏序关系。偏序关系是描述有向图的另一种方式,它为我们提供了一个关于数学结构公理化数学思想的有趣案例。我们将从讨论用于公理化偏序关系和有向图的一些基本属性开始。

传递性

上一节我们介绍了有向图中的路径概念。本节中,我们来看看路径的一个基本属性:传递性

考虑有向图中的路径。如果存在一条从顶点 u 到顶点 v 的路径,以及一条从顶点 v 到顶点 w 的路径,那么将这两条路径连接起来,就得到了一条从 uw 的路径。

用有向图 G 的正路径关系 G+ 来表达,这意味着:如果 u G+ vv G+ w,那么 u G+ w

将这个属性抽象到任意关系上,就得到了传递性的定义。对于一个定义在集合 A 上的关系 R(即 R 的定义域和陪域相同),如果满足 u R vv R w 能推出 u R w,那么这个关系就是传递的

我们刚刚看到,任何有向图 G 的正路径关系 G+ 都是传递的。另一种理解传递性的方式是:u R v 表示存在一条从 uv 的边。传递性意味着,如果存在从 uv 的边和从 vw 的边,那么也必须存在一条从 uw 的边。换句话说,如果存在一条长度为2的路径,那么就必须存在一条长度为1的路径。通过简单的归纳法可以得出,如果两个顶点之间存在任何正长度的路径,那么它们之间也存在一条长度为1的路径。

以下是传递性的核心定义:

关系 R 是传递的,当且仅当 R 等于某个有向图 G 的正路径关系 G+

这个定理的证明基本上是*凡的:我们可以让关系 R 本身作为有向图的边集,那么 R 自然就是该图的正路径关系。

非对称性与严格偏序

现在,让我们转向有向无环图。在有向无环图中,如果存在一条从顶点 u 到顶点 v 的正长度路径,那么由于图中没有环,就不可能存在一条从 v 回到 u 的路径。这个属性被称为非对称性

因此,DAG 中的正路径关系 D+ 具有非对称性:如果 u 能通过正长度路径到达 v,那么 v 就不可能通过正长度路径回到 u

将这个属性抽象出来:对于一个任意关系 R,如果 u R v 能推出 非(v R u),那么这个关系就是非对称的。根据定义,无环有向图 DD+ 关系是非对称的。

严格偏序就是一个同时满足传递性非对称性的关系。

以下是严格偏序的一些例子:

  • 集合间的真包含关系:如果集合 A 真包含于集合 B,那么 B 不可能真包含于 A
  • MIT 课程间的间接先修关系:如果课程 A 是课程 B 的先修课,那么 B 不可能是 A 的先修课。
  • 实数上的小于关系:如果 x < y,那么 y 不可能小于 x

综合之前的推理,我们可以得出一个重要结论:

一个关系 R 是严格偏序,当且仅当 R 是某个有向无环图 D 的正路径关系 D+

因此,定义严格偏序的公理(传递性和非对称性)抽象地刻画了“关系来源于一个有向无环图”这一特性。

全序性

偏序的另一个重要属性是全序性(有些作者称之为线性)。

全序性的简单定义是:对于任意两个不同的元素,其中一个必定“大于”另一个(相对于该关系而言)。

最熟悉的例子是实数上的小于关系小于等于关系。给定任意两个不同的实数 xy,要么 x < y,要么 y < x

形式化定义如下:对于一个关系 R,如果对于任意 x ≠ y,都有 x R yy R x 成立,那么这个关系就是全序的

另一种说法是:在关系 R 下,不存在不可比较的元素。全序关系看起来就像一条链:给定一组元素,总会有一个最大的,然后是次大的,依此类推(假设是有限集)。

全序的基本例子是数字间的大小关系(如 <)。非全序的基本例子是集合的包含关系,因为完全可以存在两个集合,它们互不包含。

自反性与弱偏序

弱偏序是严格偏序的一个小变体,也是一个熟悉的概念。它放松了严格偏序中“元素不能与自身相关”的限制。

在弱偏序中,我们不仅放松了这个限制,反而要求每个元素都必须与自身相关

弱偏序的例子包括:

  • 集合间的(非严格)包含关系A ⊆ A 总是成立。
  • 实数上的小于等于关系x ≤ x 总是成立。

区分弱偏序和严格偏序的属性是自反性。一个定义在集合 A 上的关系 R自反的,当且仅当对于 A 中的所有元素 a,都有 a R a

我们可以立即观察到,有向图的路径关系 G*(包括长度为0的路径)是自反的,因为根据定义,从任何顶点到其自身都存在一条长度为0的路径。

反对称性

当我们引入自反性后,需要调整非对称性的概念,使其允许元素与自身相关。调整后的属性称为反对称性

更精确地说,反对称性与非对称性的区别在于:

  • 在非对称性中,a R a 是绝对不允许的。
  • 在反对称性中,a R a 是允许的,不被禁止。

一个关系的反对称性形式化定义为:如果 u R vu ≠ v,那么 非(v R u)。第一行是非对称性的陈述,附加条件是它只在 uv 不相等时才必须成立。这就是形式化地说“反对称性等同于非对称性,但允许 a R a”。

包含长度为0路径的有向图路径关系 G*反对称的

总结:偏序的公理化

现在,让我们把所有这些概念整合起来。

  • 弱偏序传递的反对称的自反的关系。在弱偏序中,我们要求每个元素都与自身相关。
  • 严格偏序传递的非对称的关系。在严格偏序中,没有元素与自身相关。

一个简短的说明:非对称性意味着没有元素与自身相关;自反性意味着所有元素都与自身相关。可能存在某些图,其中一些元素与自身相关,另一些则不,这样的关系只是传递且反对称的,但它们不常出现,因此我们不给它们专门命名。

最后,总结整个故事的定理是:

一个关系 R 是弱偏序,当且仅当 R 等于某个有向图 G 的路径关系 G*

本节课中,我们一起学*了偏序关系的核心概念:传递性非对称性/反对称性自反性严格偏序弱偏序以及全序性。我们看到了这些抽象的公理性质如何精确地对应到有向图(特别是有向无环图)的路径关系上,从而将图论与序论紧密地联系起来。

计算机科学的数学基础:P52:L2.7.3- 将偏序关系表示为子集关系 📚

在本节课中,我们将学*偏序关系的一个重要性质:表示定理。我们将看到,任何严格的偏序关系在结构上都等同于某个集合族在真包含关系下的偏序。这为我们理解抽象的偏序关系提供了一个非常直观的模型。


回顾与引入

上一节我们介绍了偏序关系及其在有向无环图中的表示。本节中,我们来看看偏序关系的另一种理解方式——将其与集合的包含关系联系起来。

从例子出发:真子集关系

我们首先关注真子集关系。集合 A 是集合 B 的真子集,记作 A ⊂ B,其含义是 B 包含了 A 中的所有元素,并且还包含一些额外元素。因此,B 不可能是 A 的子集(更不用说真子集)。

考虑以下七个集合,箭头(图中向上指)表示它们之间的真子集关系(即正路径关系):

{1} ⊂ {1,5} ⊂ {1,2,5,10}
{5} ⊂ {1,5} ⊂ {1,2,5,10}
{2} ⊂ {1,2,5,10}
{1,2,5,10} 是最大的集合。

这种图被称为哈斯图,其中高度暗示了箭头的方向(向上)。例如,从集合 {1} 到集合 {1,5} 有一条向上的路径,因为 {1,5} 包含了 {1} 中的元素 1 以及额外元素 5。同样,从 {1}{1,2,5,10} 也有路径。

一个相似的例子:真整除关系

现在,让我们看一个结构非常相似的例子:真整除关系。我们说 a 真整除 b,如果 a 整除 ba ≠ b

考虑在以下七个数字上的真整除关系:{1, 2, 3, 5, 10, 15, 30}。其哈斯图如下:

1 → 2, 3, 5
2 → 10
3 → 15
5 → 10, 15
10 → 30
15 → 30

这个图的关键在于,这七个数字在真整除关系下的结构图,与之前那七个集合在真子集关系下的结构图形状完全相同。我们可以将一个图叠加在另一个图上,它们能完美匹配。

同构的概念

当两个图具有“相同形状”时,我们在数学上称它们为同构的。同构意味着我们只关心顶点之间的连接关系,并且存在一个顶点间的一一对应(双射),使得连接关系得以保持。

以下是同构的正式定义:

设有向图 G1 = (V1, E1)G2 = (V2, E2)。我们说 G1G2 同构,当且仅当存在一个双射函数 f: V1 → V2,满足以下条件:
对于 V1 中的任意两个顶点 uv(u, v) ∈ E1 当且仅当 (f(u), f(v)) ∈ E2

用公式表示即:

∃ f: V1 → V2 (f 是双射 ∧ ∀ u,v ∈ V1 [(u, v) ∈ E1 ⇔ (f(u), f(v)) ∈ E2])

核心定理:偏序的表示定理

我们通过真整除和真子集的例子所展示的,实际上是一个普遍定理的特例。这个定理就是表示定理

每一个严格的偏序关系都同构于某个集合族在真包含关系 下构成的偏序。

这意味着,如果你想理解偏序关系是什么,答案就是:一个严格的偏序关系看起来就像一堆集合在包含关系下的排序。任何严格的偏序关系都可以通过一种方式,被“看作”是一组集合之间的包含关系。

定理的证明思路

这个定理的证明是直观的。给定任意一个严格的偏序关系 R(定义在集合 D 上),我们可以构造一个同构映射 f,将 D 中的每个元素映射到一个集合。

以下是构造映射的方法:

  • 对于 D 中的任意元素 a,将其映射到这样一个集合:该集合包含所有在关系 R 下“小于或等于” a 的元素。
  • 由于 R 是严格的(aRa),我们需要特意把 a 本身也加入这个集合。

用公式定义这个映射 f

f(a) = { b ∈ D | (b, a) ∈ R } ∪ {a}

或者等价地,f(a) = R^{-1}(a) ∪ {a},其中 R^{-1}(a) 表示所有与 aR 关系的元素集合。

用例子说明映射构造

让我们用之前的真整除关系例子来演示这个映射是如何工作的。我们有偏序集 D = {1, 2, 3, 5, 10, 15, 30},关系 R 是“真整除”。

以下是映射 f 的构造结果:

  • f(1) = {1} (没有数真整除1,所以只包含自身)
  • f(2) = {1, 2} (1真整除2)
  • f(3) = {1, 3}
  • f(5) = {1, 5}
  • f(10) = {1, 2, 5, 10} (1, 2, 5 真整除10)
  • f(15) = {1, 3, 5, 15}
  • f(30) = {1, 2, 3, 5, 10, 15, 30}

现在,观察这些像集合 {f(a) | a ∈ D}

{1}, {1,2}, {1,3}, {1,5}, {1,2,5,10}, {1,3,5,15}, {1,2,3,5,10,15,30}

它们在真包含关系 下形成的结构,与原始数字在真整除关系 R 下的结构是完全同构的。例如,2 真整除 10,对应地 f(2) = {1,2} 是真包含于 f(10) = {1,2,5,10}

这个构造普遍适用于任何严格的偏序关系,从而证明了表示定理。


总结

本节课中我们一起学*了偏序关系的一个深刻性质——表示定理。我们了解到:

  1. 通过真子集关系真整除关系的例子,我们发现了不同偏序结构可能具有相同的形状(即同构)。
  2. 我们正式定义了图的同构概念,它要求顶点间存在一个保持边关系的双射。
  3. 我们学*并解释了核心的表示定理任何严格的偏序关系都同构于某个集合族在包含关系下构成的偏序
  4. 我们探讨了定理证明的核心思路,即通过将每个元素映射到其“下界”集合(包括自身)来构造同构映射。

这个定理非常重要,因为它将抽象的偏序关系与非常具体、直观的集合包含关系联系了起来,为我们理解和分析偏序结构提供了一个强大的工具。在后续学*中,你可以尝试将其他偏序(如任务依赖关系)也想象成集合的包含,这常常能带来新的洞察。

计算机科学的数学基础:2.7.4:等价关系 🔗

在本节课中,我们将要学*等价关系。等价关系是定义在集合上的一种二元关系,它在数学和计算机科学中扮演着至关重要的角色。我们将从有向图的角度和公理的角度来解释等价关系,并探讨其多种表示方式。

有向图视角下的等价关系

上一节我们介绍了二元关系的基本概念,本节中我们来看看如何用有向图来理解等价关系。

等价关系可以理解为有向图中顶点之间的“双向可达”关系。具体来说,如果从顶点 u 到顶点 v 存在一条路径,并且从顶点 v 到顶点 u 也存在一条路径(包括长度为0的路径),那么 uv 就被称为强连通的。这种强连通关系就是等价关系的一个例子。

用路径关系(包括零长度路径)的符号表示,即 u G* vv G* u

等价关系的公理定义

从公理的角度看,等价关系是一种同时满足对称性传递性自反性的二元关系。

以下是这些性质的定义:

  • 对称性:一个定义在集合 A 上的关系 R 是对称的,当且仅当 a R b 蕴含 b R a
  • 传递性:关系 R 是传递的,当且仅当 a R bb R c 蕴含 a R c
  • 自反性:关系 R 是自反的,当且仅当对于集合 A 中的每个元素 a,都有 a R a

因此,有向图中的强连通关系是一个等价关系,因为它天然满足这三个性质:它是对称的(双向可达),是传递的(如果 uv 双向可达,vw 双向可达,那么 uw 也双向可达),并且是自反的(每个顶点到自身都有长度为0的路径)。

反之,任何等价关系都可以看作是某个有向图的强连通关系。

等价关系的例子

为了加深理解,我们来看几个等价关系的具体例子:

  • 相等关系:最基础的等价关系。任何元素都等于其自身(自反),如果 a = bb = a(对称),如果 a = bb = ca = c(传递)。
  • n 同余:两个整数 abn 同余(记作 a ≡ b (mod n)),当且仅当 n 整除 (a - b)。这个关系也满足自反、对称和传递性。
  • 集合等势:对于有限集,如果两个集合的元素个数相同,则它们等势。这也是一个等价关系。
  • 颜色相同:定义在一组有颜色的物体上,如果两个物体颜色相同,则它们具有该关系。这同样是一个等价关系。

性质的有向图表示

我们可以用有向图来直观地记忆这些性质:

  • 自反性:图中每个顶点都有一个指向自身的环(自环)。
  • 传递性:如果图中存在一条从 uv 再到 w 的长度为2的路径,那么必然存在一条从 u 直接到 w 的边。
  • 对称性:如果图中存在一条从 uv 的边,那么必然存在一条从 v 回到 u 的边。

等价关系的其他表示法

除了用有向图表示,等价关系还有两种非常重要的等价表示方式。

1. 通过函数定义

给定一个从集合 A 到陪域 B全函数 f,我们可以定义一个等价关系 Equiv_f

a Equiv_f a' 当且仅当 f(a) = f(a')

即,两个元素等价当且仅当它们在函数 f 下的像相同。由于“相等”是等价关系,Equiv_f 自然继承了自反、对称和传递性。

定理:集合 A 上的一个关系 R 是等价关系,当且仅当存在某个函数 f,使得 R 等于 Equiv_f

例如,模 n 同余关系就可以通过函数 f(k) = k mod nk 除以 n 的余数)来定义。两个数同余当且仅当它们被 n 除的余数相同。

2. 通过划分定义

一个集合 A划分,是将 A 分割成若干个互不相交的非空子集(称为),使得 A 中的每个元素都恰好属于其中一个块。

给定一个划分,我们可以定义一个等价关系:两个元素等价,当且仅当它们属于划分中的同一个块。

反之,定理:集合 A 上的一个关系 R 是等价关系,当且仅当它是 A 的某个划分的“属于同一块”关系。

从函数表示到划分表示的思路是:将元素映射到它所属的块,这个映射本身就是一个函数。反之,从一个等价关系出发构造其对应的划分,是一个基础的公理化推理练*。


本节课中我们一起学*了等价关系。我们首先从有向图中“强连通”的概念引入,然后给出了等价关系必须满足的三个公理:自反性对称性传递性。接着,我们探讨了等价关系的多种表示方法,包括有向图表示、通过函数定义以及通过集合划分定义。理解等价关系的这些不同视角,对于后续学*数学和计算机科学中的许多概念(如商集、同余类等)至关重要。

图论基础:2.8.1:顶点的度 📊

在本节课中,我们将学*图论中的一个新主题——简单图,并重点介绍一个核心概念:顶点的度。我们将从简单图的定义开始,逐步理解度的概念,并学*一个重要的定理——握手定理。最后,我们将通过一个有趣的社会学应用,展示图论如何帮助我们分析现实世界的数据。


简单图与有向图

上一节我们讨论了有向图,其中有向边具有起点和终点。本节中,我们来看看一种更简单的图结构。

简单图比有向图更简单。它的边没有方向,只代表一种对称的、相互的连接关系。下图展示了一个简单图,其边没有箭头。

有向图的一个特点是,两个顶点之间可以存在两个方向相反的箭头。但在简单图中,由于边是无向的,这种情况不会发生。因此,在简单图中,一对顶点之间最多只有一条边。

此外,有向图允许存在自环,即一条边从同一个顶点出发并结束。简单图则不允许自环。当然,存在允许自环和多条边的“多重图”,但为了不使问题复杂化,我们目前只讨论简单图。


简单图的正式定义

简单图是一个对象 G,它包含两个部分:

  1. 一个非空的顶点集合 V
  2. 一个边集合 E

由于边没有方向,一条边只有两个端点,且这两个端点没有顺序之分。下图展示了一个包含6个蓝色顶点和7条绿色边的简单图。

图中,我们用黄色和红色高亮了一条边(深绿色)。在形式上,这条边可以表示为它的两个端点组成的集合:{红, 黄}。在文本中,我们常用一条横线连接两个顶点来表示,例如 红—黄。必须记住,顶点的顺序无关紧要,因为它本质上是一个集合。

当两个顶点被一条边连接时,我们称它们是相邻的。同时,这条边关联于它的两个端点。


顶点的度

图论中的一个基本概念是顶点的。一个顶点的度,就是关联于该顶点的边的数量,即连接到该顶点的边的条数。

让我们来看图中的例子:

  • 红色顶点有两条边与之相连,所以它的度是 2
  • 黄色顶点有四条边与之相连,所以它的度是 4


握手定理

现在,让我们探讨顶点度的一个基本性质,这引出了一个非常重要的定理。

假设我们有一个包含三个顶点的图,其度数分别为 2、2 和 1。我们能画出这样的图吗?通过尝试,我们会发现这是不可能的。我们可以用一个更通用的定理来证明这一点,而无需具体画图。

这个定理被称为握手定理。它指出:一个图中,所有顶点的度数之和,等于边数的两倍

用公式表示如下:

∑_{v ∈ V} deg(v) = 2 * |E|

其中:

  • ∑_{v ∈ V} deg(v) 表示对所有顶点 v 的度数 deg(v) 求和。
  • |E| 表示边集合 E 的大小,即边的数量。

为什么这个定理成立?
因为每条边都关联两个顶点。在计算所有顶点的度数之和时,每条边都被计算了两次(分别在其两个端点的度数中各计一次)。因此,总和必然是边数的两倍。

回到我们之前的例子:度数 2、2、1 的和是 5,这是一个奇数。根据握手定理,这个和必须是偶数(因为它是边数的两倍)。所以,我们立刻可以断定,不可能存在一个顶点度数为 2、2、1 的图。


应用:一个社会学问题

现在,让我们应用握手定理来分析一个有趣的社会学问题:男性是否比女性拥有更多的性伴侣?

多项调查反复显示,男性报告的*均性伴侣数量比女性多出30%到数倍。这看起来很奇怪,我们将用一个简单的图论模型来论证这个结果在数学上是不可能的。

构建模型

我们用一种特殊的简单图——二分图来建模两性关系。

  • 我们有两组顶点:集合 M(代表男性)和集合 F(代表女性)。
  • 如果一位男性和一位女性发生过性关系,我们就在他们对应的顶点之间连一条边。

在这个模型中,每条边都连接一个男性顶点和一个女性顶点。

应用握手定理

现在,我们分别对男性顶点和女性顶点应用握手定理的思想:

  • 所有男性顶点的度数之和,等于图中的总边数(因为每条边恰好连接一位男性)。
  • 所有女性顶点的度数之和,也等于图中的总边数(因为每条边恰好连接一位女性)。

因此,我们得到以下等式:

∑_{m ∈ M} deg(m) = |E| = ∑_{f ∈ F} deg(f)

即:男性度数之和 = 女性度数之和

推导*均伴侣数

接下来,我们在这个等式两边做一些简单的算术变换。首先,等式两边同时除以男性总人数 |M|

(∑_{m ∈ M} deg(m)) / |M| = (∑_{f ∈ F} deg(f)) / |M|

左边 (∑_{m ∈ M} deg(m)) / |M| 正是男性*均拥有的伴侣数,记作 Avg_deg(M)

为了处理右边,我们引入女性总人数 |F|

(∑_{f ∈ F} deg(f)) / |M| = [(∑_{f ∈ F} deg(f)) / |F|] * (|F| / |M|)

这里,(∑_{f ∈ F} deg(f)) / |F|女性*均拥有的伴侣数,记作 Avg_deg(F)|F| / |M|女性与男性的人口比例

于是,我们得到了一个关键公式:

Avg_deg(M) = Avg_deg(F) * (|F| / |M|)

男性*均伴侣数 = 女性*均伴侣数 × (女性人口 / 男性人口)

结论分析

这个公式告诉我们,两性*均伴侣数的差异,完全由人口性别比例决定,而与行为差异无关。

以美国为例,女性与男性的比例约为 1.035 : 1。代入公式:

  • 如果女性*均有 10 个伴侣,那么男性*均应有 10 × 1.035 = 10.35 个伴侣。
  • 男性*均伴侣数仅比女性高出约 3.5%,远非调查中显示的 30% 或更高。

因此,那些显示男性伴侣数远高于女性的调查数据,在数学上是不可能的。数据矛盾的原因很可能在于报告偏差:例如,男性可能夸大了数量,而女性可能少报了数量。但无论如何,图论模型清晰地揭示了原始数据中的逻辑谬误。


总结

本节课中,我们一起学*了:

  1. 简单图的定义:由顶点集和无向边集构成,没有重边和自环。
  2. 顶点的:关联于该顶点的边的数量。
  3. 握手定理:所有顶点度数之和等于边数的两倍,即 ∑ deg(v) = 2|E|
  4. 一个精彩的应用:利用二分图和握手定理,我们证明了关于两性伴侣数量的某些流行调查数据在数学上不成立,并推导出*均伴侣数只与人口性别比例相关的结论。

这个例子生动地展示了,图论不仅是抽象的数学工具,也能为分析现实世界的社会现象提供清晰而有力的逻辑框架。

计算机科学的数学基础:2.8.3:图的同构 📊

在本节课中,我们将要学*图论中的一个核心概念——图的同构。我们将了解如何判断两个看似不同的图在结构上是否完全相同,以及如何证明它们不同。

概述

图是描述节点(顶点)和它们之间连接(边)的数学结构。有时,同一个图可以用不同的方式绘制,或者给顶点赋予不同的标签。图的同构概念帮助我们判断两个图在本质上是否“相同”,即它们是否具有完全相同的连接结构,而忽略其外观或标签的差异。

什么是图的同构?

上一节我们介绍了图的基本概念,本节中我们来看看如何定义两个图的“相同性”。

图本身只由顶点集和边集组成。考虑以下两个图,它们虽然画法不同,但顶点和边的连接关系完全一致,因此是同一个图的不同布局。

现在看另一个例子。下图中的两个图,布局完全相同,但顶点的标签不同。左边的顶点是整数,右边的顶点是人名。

这两个图被称为同构的。同构意味着两个图具有相同的连接模式。更正式的定义是:

两个图 G1G2 是同构的,当且仅当存在一个从 G1 顶点集到 G2 顶点集的双射函数 f,并且该函数保持边的关系。即,在 G1 中,顶点 uv 之间有边,当且仅当在 G2 中,顶点 f(u)f(v) 之间也有边。

用公式表示如下:

对于图 G1 = (V1, E1) 和图 G2 = (V2, E2),若存在双射 f: V1 → V2,使得对于任意 u, v ∈ V1,都有:
(u, v) ∈ E1 ⇔ (f(u), f(v)) ∈ E2
则称 G1G2 同构。

同构示例

让我们通过一个具体的例子来理解同构。考虑以下两个图:

  • 左图:顶点是动物(狗、猫、牛、猪)。
  • 右图:顶点是动物食物(牛肉、金枪鱼、干草、玉米)。

我声称这两个图是同构的。我们可以定义一个双射函数 f

以下是顶点之间的映射关系:

  • f(狗) = 牛肉
  • f(猫) = 金枪鱼
  • f(牛) = 干草
  • f(猪) = 玉米

现在,我们需要验证这个映射是否“保持边”。这意味着左图中相连的顶点,其映射在右图中也必须相连;左图中不相连的顶点,其映射在右图中也必须不相连。

  • 检查边:左图中,狗和猪之间有边。映射后,牛肉和玉米之间在右图也有边,符合条件。
  • 检查非边:左图中,牛和猪之间没有边。映射后,干草和玉米之间在右图也没有边,符合条件。

逐一检查所有顶点对后,可以确认这个双射 f 满足同构定义,因此这两个图是同构的。

如何证明两个图不同构?

要证明两个图同构,只需找到一个满足条件的双射并验证即可。但要证明两个图不同构,则需要证明不存在这样的双射。

一个有效的方法是寻找在同构下保持不变的性质。如果图 G1 具有某个性质,而图 G2 不具有该性质,那么它们就不可能同构。

以下是一些在同构下保持不变的性质:

  • 顶点数量:同构的图必须有相同数量的顶点。
  • 边的数量:同构的图必须有相同数量的边。
  • 顶点的度数序列:每个顶点的连接数(度数)必须相同。例如,一个图中有一个度数为2的顶点,另一个图中也必须有一个度数为2的顶点与之对应。
  • 子图结构:是否存在特定长度的环(圈)、路径等。

让我们看一个例子。考虑以下两个图:

它们都有四个顶点。但是,左图有两个度数为2的顶点(用红色标出),而右图所有顶点的度数都是3。由于“顶点的度数”是一个在同构下保持不变的性质,这两个图不可能同构。左图的2度顶点在右图中找不到对应的2度顶点来映射。

图同构问题的复杂性

对于小型图,我们可以通过观察或系统性的尝试来寻找同构。然而,对于具有数百甚至数千个顶点的大型图,判断它们是否同构是一个非常困难的问题。

  • 从理论上讲,图同构问题目前既未被证明是多项式时间可解的(P问题),也未被证明是NP完全问题。它是一个具有特殊计算地位的难题。
  • 从实践上讲,存在一些非常高效的算法和程序,能够在大多数实际情况下快速判断两个图是否同构。这些算法利用了图的许多结构性质(如前面提到的度数、邻接关系等)来大幅缩小搜索空间。

尽管如此,在最坏情况下,还没有一个已知的算法能保证对所有图都在多项式时间内解决同构问题。下图展示了一个复杂网络的例子,判断这样的两个图是否同构非常具有挑战性。

总结

本节课中我们一起学*了图的同构。

  • 我们理解了图的同构定义了图在结构上的“相同性”,它只关心顶点之间的连接关系,而忽略图的绘制方式或顶点标签。
  • 我们学*了同构的正式定义,即存在一个保持边关系的顶点双射。
  • 我们掌握了证明两个图同构的方法(构造双射并验证),以及证明两个图不同构的方法(寻找在同构下不变的性质差异)。
  • 最后,我们了解了图同构问题的计算复杂性,知道它在理论上的困难性和在实际中的可处理性。

理解同构是图论的基础,它帮助我们抓住图的本质结构,是后续学*图分类、图算法等内容的重要工具。

图论基础:2.9.1:图着色 🎨

在本节课中,我们将要学*图论中的一个核心概念——图着色。图着色是许多现实世界冲突调度问题的抽象模型,例如飞机登机口调度、考试时间安排等。我们将通过具体例子来理解其定义、应用和基本性质。

从实际问题到抽象模型

上一节我们介绍了图的基本概念,本节中我们来看看如何用图来建模冲突问题。图着色是多种冲突调度情况的抽象版本。让我们先看一个例子,然后定义问题。

设想有一批飞机需要在地面机场的登机口进行调度。如果两架飞机同时在地面,它们需要被分配到不同的登机口,因为一个登机口一次只能服务一架飞机。我们需要解决的问题是:为了服务所有可能同时在地面的飞机,最少需要多少个登机口?

让我们看一个示例日程表。这里有六个航班,编号从120到145,以及99。水*条表示一天中的时间,蓝色块表示航班在地面的时间段。例如,航班122从凌晨3点到7点在地面。航班145在地面的时间段则完全不同且不重叠。航班67到57从午夜到大约早上6点在地面,它与航班122的时间有重叠。根据这些信息,我们需要确定需要多少个登机口。

我们可以想象一条垂直的绿线在时间条上滑动,观察绿线在任何时刻穿过的蓝色区间的最大数量。在这个例子中,最大数量是3。这意味着在任何给定时刻,最多有3架飞机在登机口,因此我们只需要3个登机口就能应对冲突。

构建冲突图

抽象地,我们将每架飞机视为图的一个顶点。我们将在两个顶点之间添加一条边,来表示它们之间的冲突(而非兼容性)。这与之前匹配例子中寻找兼容性不同。这里的边意味着两架飞机同时在地面,它们发生冲突,需要不同的登机口。

例如,航班306和145同时在地面,它们之间有一条边。同样,航班99和145也同时在地面。这三架飞机(306、145、99)在某个时刻同时在地面,这反映在图中它们构成了一个三角形。如果我为所有其他顶点填充这个图,并在两架飞机同时在地面时画一条边,最终会得到一个小图。

图着色问题定义

现在我们可以抽象地讨论着色问题:为图的顶点分配颜色,使得任何两个相邻的顶点不具有相同的颜色。相邻的顶点必须有不同的颜色。

从我们如何根据航班日程表推导出这个图的描述中可以清楚地看出,为图着色所需的最少不同颜色数量,对应于服务这些飞机所需的最少登机口数量。

让我们尝试为这个图着色。我从为航班257涂红色、122涂黄色、99涂绿色开始。这里没有一般性的损失,因为这三架飞机同时在地面(反映在它们构成一个三角形的事实上),我必须使用三种不同的颜色,因为每架飞机都与其他两架相邻。

接下来,我为145涂黄色。既然它不与任何黄色顶点相邻,我可以重用黄色。然后,这里又有一个三角形。如果我不想使用额外的颜色,合理的做法是将它涂成红色。但这里我用了红色。还有一个三角形,这允许我涂色。然后我将这个顶点涂成黑色,因为我被卡住了:它同时与黄色、黑色和绿色顶点相邻,所以我必须想出第四种颜色。

我们用了四种颜色完成着色,这意味着我们本可以用四个登机口应付。颜色告诉我们哪架飞机分配到哪个登机口。例如,257和67可以分配到红色登机口,因为它们不同时在地面(它们之间没有边)。122和145可以分配到黄色登机口,依此类推。

然而,这不是最聪明的着色方式。这里展示了一种更好的着色方案。你可以检查每两个相邻顶点都有不同的颜色,现在我只用了三种颜色:红、黄、绿。这意味着只需要三个登机口,我得到了一个更好的调度方案。

更多应用场景

这种冲突建模的情况经常出现。另一个例子是安排期末考试。如果有一个学生同时选修两门课程,那么这两门课就存在冲突,因为它们的期末考试不能安排在同一时间。因此,我需要为有共同学生的课程对分配不同的考试时间段。问题在于,给定关于哪些课程对有共同学生的数据,我们想知道最短的考试周期可以是多长。这又变成了一个简单的图模型和着色问题。

这里我们画了一个图,包含一些示例课程。6042和1802有一条边,表示它们有共同的学生,因此期末考试需要安排在不同时间。同样,802和6042也有共同学生,所以需要安排在不同时间。另一方面,6042和1802(此处应为3091和1802)之间没有边,这意味着它们可以安排在同一时间,至少根据此图中的数据,没有学生同时选修3091和1802。

让我们尝试着色。同样,这里有一个三角形,我必须为三角形使用三种不同的颜色。这里有另一个三角形,为了节省颜色,让我们重用绿色。现在,这里有一个顶点与三个不同颜色的顶点相邻,因此它必须用第四种颜色着色。这次,四种颜色被证明是最佳可能方案。你可以检查这一点,它对应于一个调度方案。

这种冲突建模情况无处不在。另一个会出现这类兼容性图或不兼容性图(你需要为其着色)的地方是管理动物园。你必须为某些不能混在一起的动物物种准备独立的栖息地。在大鱼吃小鱼的水族馆世界里,你需要将大鱼和小鱼分开。你也不希望老虎和黑猩猩住在一起。我们可以再次将此问题建模为:我们需要多少个笼子?我们为每个物种创建一个顶点,并在两个不能共享栖息地或笼子的物种之间画一条边。

另一个例子是为广播电台分配不同频率。如果两个广播电台彼此靠*,它们会相互干扰,因此必须分配不同的颜色或频率。现在,我们将广播电台作为顶点,将距离*到会相互干扰的广播电台用边连接起来,表示它们需要分配不同的频率。

一个经典的例子是字面意义上的地图着色。如果你试图为美国地图着色,使得任何两个共享边界的州不具有相同的颜色。这是一个用四种颜色着色的示例。问题是,如果我给你某种*面地图,最少需要多少种颜色?如果两个国家只在一个点相接,允许它们共享颜色;但如果它们共享一段正长度的边界,则必须使用不同颜色。

地图着色与四色定理

将这个问题转化为顶点着色问题的方法是:如果你有一个像这样的*面图(这里只是一个任意的例子),我感兴趣的是用不同颜色为区域(国家)着色。但我会用顶点替换每个区域。我将在每个区域的中间放置一个顶点。注意这里有一个外部区域,它也得到了一个顶点。所以有六个区域,六个顶点。然后,我只需在两个区域共享一段正长度边界时连接对应的两个顶点。

例如,这条边对应于这个区域和那个区域共享的这段边界。如果你看这个相同的三角形区域,它与外部区域共享边界,因此会有一条从这里到代表外部区域的顶点的边。其余的边也是如此:当两个区域共享边界时,它们之间就有一条边。现在,问题是为国家着色对应于为顶点着色,我们希望用尽可能少的颜色为图着色。

一个在七十年代被证明的著名结论是:每个*面图实际上都是四色可着色的。这个结论在19世纪50年代首次被声称证明,但事实上发表的证明是错误的。它在期刊文献中搁置了十年,才有人发现了一个错误。也就是说,证明是错的,但结论本身可能没错。证明中存在一个未被充分论证的大漏洞。该证明确实为五色定理提供了正确的论证,而四色问题则悬而未决。

后来,两位数学家提出了四色定理的证明,但这个证明非常有争议,因为其大部分内容需要一个计算机程序来遍历数千个需要验证是否为四色可着色的样本图。他们有一个论证表明,如果存在任何不能被四着色的图,那它将是这几千个图中的一个。然后他们着手为这几千个图着色,这些图是在计算机的帮助下生成的,着色也是在计算机和手工的帮助下完成的。这让数学界很不满意,因为这样的证明本质上是无法人工核验的。

在20世纪90年代开发了一个改进得多的版本,但它最终仍然需要一个计算机程序来生成大约600张地图并验证它们的可着色性。因此,寻找一个无需计算机辅助、人类可以理解的四色定理证明,仍然是一个目标。但在数学界,对这个定理已不再有真正的怀疑。

色数与基本性质

如果我取一个任意图,并问为其着色所需的最少颜色数是多少,这被称为图的色数。所以,χ(G) 是为图G着色的最少颜色数。

让我们看看不同类型图的色数。

  • 偶环:这里有一个长度为4的简单环。显然它可以用两种颜色着色,只需交替着色。这可以推广到任何偶数长度的环:偶数长度环的色数就是2,你可以交替为顶点着色。
  • 奇环:另一方面,如果环的长度是奇数,你将需要第三种颜色。这是无法避免的,因为即使你尝试只用两种颜色,当你交替着色并绕回起点时,你会发现无法交替着色,为了避免冲突,你将需要第三种颜色。因此,一般来说,奇数长度环的色数是3。
  • 完全图:这里展示了一个5个顶点的完全图。这是一个5顶点图,其中每个顶点都与其他四个顶点相邻。由于每个顶点都与其他四个顶点相邻,你将需要五种颜色。你无法做得更好,它们都必须有不同的颜色。因此,在n个顶点上的完全图(其中每个顶点都与其他n-1个顶点相邻)的色数是n。
  • 轮图:另一个简单的例子是,如果我取一个环,在中间加一个轴心,称之为轮图。那么,外面有一个长度为5的环(周长为5)的轮图称为W5。我们可以用四种颜色为它着色。一般来说,奇数长度轮图的色数为4的论证是:我知道我需要三种颜色来为轮缘着色,而由于轴心与轮缘上的所有顶点都相邻,我需要为它准备第四种颜色。另一方面,如果周长是偶数,我可以用三种颜色应付。

关于色数还有一个简单的论证:如果一个图的每个顶点的度数最多为K(即任何给定顶点最多与K个其他顶点相邻),那么这意味着该图是K+1可着色的。证明是构造性的且非常简单:基本上,你可以以任何你喜欢的方式开始为顶点着色,但要遵守一个约束:当你为一个顶点着色时,它不能与周围任何顶点的颜色相同。但这很容易做到,因为当需要为某个顶点着色时,即使它周围的所有顶点都已着色,也最多只有K个,所以我总能找到第K+1种颜色分配给它,从而得到一个令人满意的着色。因此,我可以用K+1种颜色应付。

着色问题的计算复杂性

一般来说,检查一个图是否是2可着色实际上非常容易,我们可能会在一些课堂问题中讨论。但3可着色性则发生了巨大变化——我们回到了NP完全问题的领域。事实上,我的一位学生大约40年前的一个结果是:即使一个图是*面的(你知道它肯定可以用四种颜色着色),确定它是否可以用三种颜色着色,其难度与可满足性问题相当,并且实际上是一个NP完全问题。事实上,如何将可满足性问题归约为可着色性问题的证明,出现在教材的一个问题中,我们可能会将其作为*题集的问题。

因此,一般来说,即使只针对三种颜色,找到χ(G)也是困难的。从理论角度来看,检查χ(G)是否为某个非常大的数,其难度并不比检查三着色更糟。但从实际角度来看,三着色比n着色更容易检查。


本节课中我们一起学*了图着色的基本概念。我们了解到图着色是建模冲突调度问题的强大工具,例如飞机登机口分配和考试安排。我们定义了色数χ(G),并探讨了不同类型图(如环、完全图、轮图)的色数。我们还简要介绍了著名的四色定理及其历史,并指出了检查图是否三着色是一个NP完全问题,这意味着在一般情况下寻找最优着色方案是计算困难的。理解这些基础是学*更高级图论算法和应用的第一步。

计算机科学的数学基础:L2.9.3:图的连通性 🔗

在本节课中,我们将要学*图论中的一个核心概念——连通性。我们将从关系语言转向图论语言,以便更好地讨论路径和连接。本节将介绍顶点和图的连通性定义,以及连通分量的概念。

从关系到图论

上一节我们介绍了图的基本概念。本节中我们来看看如何描述图中顶点之间的连接关系。从关系语言切换到图论语言的核心目的,是为了能够讨论路径和连通性。

顶点连通性

在简单图或有向图中,两个顶点被认为是连通的,当且仅当它们之间存在一条路径。在有向图中,路径具有方向;在简单图中,路径没有方向。因此,如果顶点A与顶点B连通,那么顶点B也与顶点A连通,这是一种对称关系。

定义:两个顶点连通当且仅当它们之间存在一条路径。这等价于说它们之间存在一条游走。我们包括长度为0的路径(即零步游走),因此每个顶点都被认为与自身连通。

图的连通性

一个图被称为是连通的,当且仅当它的所有顶点都彼此连通。这意味着从图中的任意一个顶点出发,都可以通过路径到达其他任何顶点。

连通分量

并非所有图都是连通的。任何图都可以被分解为若干个相互连通的子图,这些子图被称为它的连通分量。

以下是连通分量的一个简单示例:

考虑麻省理工学院(MIT)建筑之间的连接关系。如果两栋建筑之间有门或走廊相连,我们就在它们之间画一条边。

  • 建筑10和建筑4之间有走廊。
  • 建筑10和建筑12之间没有直接连接,要到达12必须经过4。
  • 东校区(East Campus)与任何建筑都不相连,因此它是一个孤立的顶点。
  • 医疗中心(Medical Center)的E17和E25等四栋建筑按指示连接,但与东校区或主长廊(Infinite Corridor)完全不相连。

这是一个图,但它不是三个独立的图。它是一个包含三个部分的图,因此它有三个连通分量。

一般来说,一个图的连通分量越多,它就越“破碎”。这是一个便于记忆的方式。

连通分量的形式化定义

顶点V的连通分量,简单地定义为所有与V连通的顶点W的集合。观察这些连通分量,它们实际上定义了顶点集上的一个等价关系。因为连通分量是该等价关系的一个块,也是与该等价关系相关的划分的一个块。

另一种定义方式是:与V连通的顶点W的集合,就是顶点V在图G的“游走关系”下的像。我们用 E* 表示图G的游走关系,其中边集E包括所有长度大于等于0的游走(包括长度为0的游走)。

因此,一个图是连通的,意味着它实际上只有一个连通分量。

总结

本节课中我们一起学*了图的连通性。我们定义了顶点之间的连通关系,并由此引出了连通图的概念。对于非连通图,我们介绍了其分解为若干连通分量的方法,并给出了连通分量的形式化定义。理解连通性是分析图结构的基础,在后续课程中,我们将利用这些概念解决更复杂的问题。

图论基础:2.9.4:k-连通性 📊

在本节课中,我们将要学*图连通性的量化概念——k-连通性。连通性并非简单的“连通”或“不连通”,我们可以精确地描述一个图或一对顶点之间的连接强度。本节将介绍边连通性和顶点连通性的定义,并通过实例和常见图结构来加深理解。

边连通性

上一节我们介绍了图的基本连通性,本节中我们来看看如何量化这种连通强度。首先,我们定义两个顶点之间的边连通性。

两个顶点被称为 k-边连通 的,如果从图中删除少于 k 条边后,这两个顶点之间仍然保持连通。

以下是几个例子,用于说明这个概念:

  • 1-边连通:考虑图中两个品红色的顶点。它们是连通的,但如果删除特定的某一条边,它们就会变得不连通。因此,它们是1-边连通的,但不是2-边连通的。
  • 2-边连通:考虑图中两个绿色的顶点。你可以删除任意一条边,它们之间仍然存在路径。但如果你删除特定的两条边,它们就会变得不连通。因此,它们是2-边连通的。
  • 3-边连通:考虑图中两个紫色的顶点。你可以删除任意两条边,它们仍然保持连通。这是因为它们位于两个环中,要断开连接需要切断两个环,即至少需要删除两条边。然而,删除三条特定的边后,它们就会变得不连通。因此,它们是3-边连通的,但不是4-边连通的。

对于一个整个图,如果其中任意两个顶点都是 k-边连通 的,那么这个图就是 k-边连通 的。

顶点连通性

与边连通性相对应,我们还有顶点连通性的概念。

一个图是 k-顶点连通 的,如果删除图中任意少于 k 个顶点后,该图仍然保持连通。

需要指出的是,如果一个图是 k-顶点连通 的,那么它必然也是 k-边连通 的,但反之则不一定成立。例如,一个图可能是2-边连通的,但却是1-顶点连通的(删除某个特定顶点就会破坏连通性)。

连通性的意义与应用

连通性度量了网络的容错能力。如果将图视为一个通信网络,顶点代表信息中心,边代表连接中心的信道或电缆,那么连通性就衡量了:在多少条信道或电缆发生故障的情况下,所有信息中心之间仍然能够保持通信。

重要定理与图结构

在深入探讨具体图结构之前,我们先提及一个重要的定理——门格尔定理。该定理指出:一个图是 k-顶点连通 的,当且仅当图中任意两个顶点之间都存在 k完全不相交的路径(即路径之间没有共享的顶点)。边连通性也有一个类似的定理。这些定理直观地说明了,为了断开两个高度连通的顶点,你需要切断它们之间的每一条独立路径。

接下来,我们看看一些常见图结构的连通性。我们关心的是:要达到特定的连通级别,需要多少条边(这可以看作是构建网络的成本)。

以下是几种常见图结构的连通性与边数对比:

  • 完全图 K_n:这是 n 个顶点上连通性最强的图。它是 (n-1)-顶点连通 的,但需要大约 n^2/2 条边。公式表示为:边数 = C(n, 2) = n(n-1)/2
  • n维超立方体 H_n:它的顶点是长度为 n 的二进制串,两个顶点相邻当且仅当它们的二进制表示仅有一位不同。H_nn-顶点连通 的。对于一个具有 N 个顶点的超立方体(即 H_{log_2 N}),其边数约为 (N log_2 N)/2。它比完全图的边数少得多,但连通性也显著降低。
  • 网格图:可以想象为*面上的整数坐标点阵,每个点与上下左右四个相邻点连接。一个有限大小的网格(通常通过将边界环绕起来形成一个环面)是 4-边连通 的,边数约为 2NN 为顶点数)。
  • C_n:一个包含 n 个顶点的环是 2-边连通 的,恰好有 n 条边。
  • :树是边数最少的连通图。一棵有 n 个顶点的树恰好有 n-1 条边,并且是 1-边连通 的(删除任何一条边都会使其变得不连通)。

总结

本节课中我们一起学*了图连通性的量化指标——k-连通性。我们定义了k-边连通性k-顶点连通性,理解了它们如何衡量网络在边或顶点发生故障时的鲁棒性。我们还通过门格尔定理了解了连通性与不相交路径数之间的等价关系,并分析比较了完全图、超立方体、网格、环和树等常见图结构的连通性水*及其所需的边数代价。掌握这些概念有助于在设计通信网络、分布式系统等需要高可靠性的结构时做出合理的选择。

计算机科学的数学基础:L2.10.1:树 🌳

在本节课中,我们将要学*计算机科学中最基本的数据结构之一:。树是一种连通且无环的简单图,它广泛应用于家谱、搜索算法、游戏策略和编译器技术等多个领域。本节课我们将探讨树的定义、性质以及多种等价的描述方式。

树的定义与基本概念

上一节我们介绍了图的基本概念,本节中我们来看看一种特殊的图——树。树的最简单定义是:树是一个连通且没有循环(环)的简单图。这里的“简单图”指的是无向、无自环且每对顶点之间最多只有一条边的图。

为了准确理解这个定义,我们需要明确“循环”的含义。在简单图中,一个循环是一条长度大于2的封闭步道,且除了起点和终点相同外,路径上的所有顶点都互不相同。长度必须大于2的规定,排除了自环和长度为2的“来回边”,这些在简单图中不被视为有意义的循环。

以下是树的几个示例:

一个没有圈的简单图示例。

另一个树状结构的示例。

树的性质与等价定义

理解了基本定义后,我们来看看树有哪些关键性质,以及如何用不同的方式来描述它。这些等价定义在理论和实践中都非常有用。

切边与循环的关系
在简单图中,一条边被称为切边,如果移除这条边会使图变得不连通(即原来通过这条边连接的两个顶点之间不再有路径)。切边与循环有紧密联系:一条边不是切边,当且仅当它包含在某个循环中。因为如果一条边在循环中,移除它后,循环上的顶点仍可通过循环的另一半保持连通。

树的等价定义
基于切边的概念,我们可以得到树的第一个等价定义:树是一个连通图,其中每一条边都是切边。这意味着从树上移除任何一条边都会破坏其连通性。

由此可以推导出第二个定义:树是边数最少的连通图。换句话说,它是一个“边最小连通图”。为了让所有顶点都连通,树提供了所需的最少边数。

对于有 n 个顶点的树,其边数恰好为 n-1。这引出了第三个等价定义:树是一个具有 n 个顶点和 n-1 条边的连通图

从另一个角度看,树也可以被描述为极大无环图。一个无环图可能不连通,但你可以不断添加边将其连通而不产生循环。当它成为一棵树(即完全连通)时,你就不能再添加任何边而不形成循环了。

也许最直观有用的定义是:树是一个在任意两个顶点之间存在唯一路径的图。连通性保证了路径的存在,而唯一性则排除了循环的可能性,因为两个不同的路径会构成一个环。

以下是这些等价定义的总结:

  • 定义一:连通且无环的简单图。
  • 定义二:每条边都是切边的连通图。
  • 定义三:具有 n 个顶点和 n-1 条边的连通图。
  • 定义四:边数最少的连通图(边最小连通图)。
  • 定义五:极大无环图(无法再添加边而不产生环的连通无环图)。
  • 定义六:任意两顶点间存在唯一路径的图。

树的结构示意图。

总结

本节课中我们一起学*了这一基本数据结构。我们从其核心定义——连通无环图出发,探讨了循环与切边的概念,并学*了描述树的多种等价方式。理解这些不同的视角,能帮助我们在不同场景下更灵活地识别和应用树结构。树因其简洁和高效的结构,成为组织与连接信息的基石。

计算机科学的数学基础:L2.10.3:树的着色 🌳

在本节课中,我们将学*图论中一个重要的概念:树的着色。我们将看到,任何具有两个或更多顶点的树,其色数都是2。这意味着我们可以仅用两种颜色为树的所有顶点着色,并保证任何相邻的顶点颜色都不同。

概述

树是一种特殊的图,其特点是任意两个顶点之间都存在唯一的一条路径。我们将利用这个“唯一路径”的特性,来证明树的色数为2,并学*一种简单有效的着色方法。

树的色数为2

上一节我们介绍了树的结构特性。本节中我们来看看如何为树着色。

我们知道,树是一个图,在每对顶点之间有唯一的路径。因此,具有两个或多个顶点的树的色数为2。证明就是演示如何给它着色。

显然不能用一种颜色,因为树中至少有两个相邻的顶点。两种颜色的着色方式如下:首先选择一个任意的顶点,称之为。你可以任意选择根是什么。

每个顶点都有一条从根到该顶点的独特路径。我们利用这种唯一的路径表征来给顶点着色。

基于路径长度的着色算法

以下是具体的着色步骤:

  1. 选择一个顶点作为根。
  2. 对于图中的每一个其他顶点,计算从根到该顶点的路径长度。
  3. 如果路径长度是偶数,则将该顶点涂成红色。
  4. 如果路径长度是奇数,则将该顶点涂成蓝色(或绿色)。

这样,我们最终会交替使用红色和蓝色。关键在于,任何两个相邻的节点,它们到根的路径长度之差为1。因此,一个距离是奇数,另一个距离是偶数,从而保证了它们的颜色不同。这就是这种着色方法会奏效的原因。

判断图是否可二着色的通用方法

两种颜色着色(即可二着色)的一个通用性质是:判断一个图是否可二着色,可以采用以下方法:

  1. 开始选择一个任意的顶点,给它涂上一种颜色(例如红色)。
  2. 然后把它所有相邻的顶点都涂成另一种颜色(例如绿色)。
  3. 继续这个过程,始终用与相邻顶点不同的颜色给新顶点着色。
  4. 如果你在着色过程中没有被“卡住”(即不会出现需要给一个顶点涂色,但其相邻顶点已使用了所有可用颜色的矛盾情况),那么这个图就是可二着色的。
  5. 如果图不是可二着色的,你在着色过程中肯定会遇到矛盾而被卡住。

所以这是一个很简单的方法来计算一个图是否可二着色。

可二着色的另一个特征

可二着色性的另一个特征是:一个图是可二着色的,当且仅当它所包含的所有环(如果存在的话)的长度都是偶数

当然,树没有环,这从另一个角度解释了为什么所有树都是可二着色的。

总结

本节课中我们一起学*了树的着色。我们了解到,利用树中“任意两顶点间路径唯一”的特性,可以通过基于根节点路径长度的奇偶性,用两种颜色为树完成有效着色。我们还学*了判断一般图是否可二着色的简单方法,以及可二着色与图中环的偶数长度之间的关系。

计算机科学的数学基础:2.10.5:生成树 🌳

在本节课中,我们将学*图论中的一个核心概念——生成树。我们将了解生成树的定义,并学*如何在带权重的图中寻找最小权重生成树。

生成树的定义

上一节我们介绍了树的概念。树有多种定义,其中一种定义是:树是连接一组顶点的最小边集。这引出了在简单图中寻找生成树的想法,生成树能保持原图相同的连接性。

首先,我们给出一个精确的技术定义。图 G生成子图,是指一个包含 G 所有顶点的子图。子图意味着它包含原图顶点的一个子集和边的一个子集。而生成子图则包含所有顶点,但只是边的一个子集。

生成树的定义是:一个本身是树的生成子图。并非所有图都有生成树,因为树必须是连通的。如果原图不连通,则无法仅使用原图中的边找到一个生成树。但可以证明,如果图是连通的,则它保证存在一个生成树。

让我们看一个例子。这里有一个简单图,我们想要找到一个生成树,即一个边的选择,它连接所有顶点,并且只使用原图中的边,同时这些边构成一棵树。这就是一个生成树。图中用洋红色高亮显示的边定义了一棵树,我没有使用原图中的三条边。

这个特定的生成树选择是任意的。通常,一个图会有很多生成树。这是另一个例子,这次用的是绿色边。同样,我只使用了原图中的边,省略了三条不同的边,并使用另一组边来形成树。它没有环,并且“生成”了整个图,因为图中的每个顶点都是它的一部分。当然,它是连通的,因为它是一棵树。

实际上,有一些优美的组合理论,可以让你在给定图的邻接矩阵后,不太困难地计算出简单图中生成树的数量,但我们暂时不深入探讨。

连通图与生成树的存在性

第一个要点是:每个连通图都有一个生成树。原因很简单:你只需选择一个最小边数的连通生成子图。如果图 G 本身是连通的,根据定义,它本身就是自己的一个生成子图,因为它包含所有自己的顶点。根据良序原理,在所有连通生成子图中,存在一个具有最小边数的子图。由于它具有最小边数,它保证是一个生成树。

最小权重生成树

当问题具有更多结构时,会变得更有趣。我们不只是想找一个边数最少的生成树,在实际应用中,边通常带有权重,而我们希望找到一个最小权重生成树

这里有一个例子,我们有一个简单图,包含一些顶点和边,每条边都被赋予了一个整数权重。这种带权图的动机可以理解为:权重表示从一个顶点直接运输某种商品到另一个顶点的成本,或者表示信号通过该信道传输所需的时间。简单图常用于模拟不同地点之间的通信问题,而信道和连接通常具有不同的成本。一个很自然的问题是:在所有能让我以相同方式将所有事物连接起来的树结构中,哪种树结构的总体成本最低?即使某些边失效,我仍然希望拥有最便宜的树来连接所有顶点。

构建最小权重生成树的算法

有一种相当简单的方法来构建这样的最小权重生成树,这就是我们现在要讨论的:如何找到它?其思想是使用灰色边来构建它。

这意味着,从顶点开始,我们将开始构建一棵树。在任何时刻,我们都有一组将成为我们生成树一部分的边。这些边之间没有环,它们被称为森林,但尚未完全连通。在这个过程的每个阶段,我们将查看当前图(即我们已选择的边集)的连通分量,并将它们涂成黑色或白色,然后查看灰色边。

灰色边的定义是:一个端点为黑色,另一个端点为白色的边。在构建生成树的过程中,我将查看所有灰色边,并选择一条权重最小的灰色边。

让我们通过一个例子来弄清楚这个过程。

  • 初始状态:开始时,我没有任何边,只有孤立的顶点。这意味着我有六个连通分量,每个分量都是一个没有边的单个顶点。我可以任意将它们涂成黑色和白色。唯一的限制是必须至少有一个黑色分量和一个白色分量。这里我选择了一种任意的着色:两个顶点为白色,其他四个为黑色。
  • 识别灰色边:在这个特定着色下,灰色边被加粗显示。例如,连接黑色和白色顶点的边是灰色边;连接两个白色或两个黑色顶点的边则不是。
  • 选择最小权重灰色边:在我的灰色边中,权重分别是 4, 4, 9, 7 和 2。权重 2 是最小的灰色边权重,所以我选择那条边开始构建我的树。
  • 更新状态并重新着色:一旦我选择了那条洋红色边,我现在有一个包含五个分量的图:由这条边定义的两个顶点的分量,以及其他四个仍然没有边连接的孤立顶点。根据规则,我可以对这五个分量重新着色,只要这个新分量内的所有顶点颜色相同。这里我将这个新分量内的两个顶点都涂成黑色,其他四个孤立顶点可以任意着色。这是我的新着色。
  • 重复过程:有了这个新的着色,我可以继续识别灰色边。这次只有两条灰色边,因为我选择只有一个白色顶点。两条灰色边的权重分别是 3 和 4。最小权重是 3,所以这将是我正在构建的最小权重生成树中的下一条边。
  • 继续迭代:我继续这个过程:识别当前森林的连通分量,为每个分量分配一种颜色(同一分量内所有顶点颜色相同),找出连接不同颜色分量的所有边(灰色边),选择其中权重最小的边加入森林,然后更新状态。最终,我会得到一棵最小权重生成树。

我还没有讨论为什么这个算法有效,这在课程笔记中有解释,但我们暂时搁置,先专注于应用这个算法。

生成树算法的变体

现在有几种方法来“生长”一棵最小权重生成树。

以下是几种常见的方法:

  • Prim算法:一种方法是从任意一个顶点开始,然后围绕该顶点不断构建。你从该顶点开始,将其涂黑,其他所有顶点涂白。这意味着所有灰色边都将连接到该顶点。选择一条权重最小的灰色边。现在你有一个包含两个顶点的分量,将其涂黑,其他所有顶点涂白。通过这种方式,你始终处理一个分量,总是将其涂成一种颜色,而其他所有顶点涂成另一种颜色,从而使其不断增长。这种方法被称为Prim算法
  • Kruskal算法:另一种方法是在所有不同的连通分量中全局地找到一条权重最小的边。这意味着你在所有连通分量之间找到权重最小的边。确定该最小权重边后,你可以将其一个端点所在分量涂黑,另一个端点所在分量涂白。这将符合我们在不同颜色分量之间选择最小权重边的过程。这就是Kruskal算法
  • 并行生长:最后,你可以并行地生长多棵树。你可以从每个连通分量开始,选择连接该分量的最小权重边,因为你可以总是将一个连通分量涂成一种颜色,而将其他边涂成另一种颜色,这样所有接触给定分量的边在该着色下都是灰色的,你可以选择其中权重最小的边来增长该分量。如果这些分量彼此距离不太*,以至于边的选择不会冲突,你就可以并行地生长这些树。我开玩笑地称之为“Myers过程”。

总结

本节课中,我们一起学*了生成树的概念。我们了解到,生成树是包含原图所有顶点且本身是一棵树的子图,并且每个连通图都至少有一个生成树。当图中的边带有权重时,寻找最小权重生成树是一个重要问题。我们介绍了一种通用的构建算法,其核心思想是迭代地选择连接不同颜色分量的最小权重边(灰色边),并讨论了该算法的几种具体实现,包括Prim算法和Kruskal算法。

计算机科学的数学基础:L2.11.1:稳定匹配问题 🎯

在本节课中,我们将学*一个经典的组合优化问题——稳定匹配问题。我们将了解其定义、一个直观但不稳定的贪心匹配示例,以及该问题在现实世界中的广泛应用。


问题定义与动机

我们之前已经见过涉及男孩和女孩及其之间连接的图。在人口统计计算的背景下,一个类似的问题出现了,即稳定匹配。这同样是一个根据某些约束条件,以特定方式将男孩和女孩进行配对的问题。

事实证明,这个问题拥有许多实际应用,我们将在课程末尾讨论。

让我们先看看问题是什么。设定如下:有一定数量的男孩(本例中为5个,编号1至5)和同等数量的女孩(标记为A至E)。每个男孩对女孩有一个偏好排序(不同男孩的排序不同),同样,每个女孩对男孩也有一个偏好排序(不同女孩的排序不同)。

例如,女孩A最喜欢男孩3,其次喜欢男孩5;而男孩1最喜欢女孩C,最不喜欢女孩D。

问题的核心是:我们希望让所有男孩与所有女孩结婚,形成五对一夫一妻制的婚姻。我们希望以一种模糊的方式考虑这些偏好,并尽可能满足它们。稍后我们会更具体地定义“满足”。


一个不稳定的贪心匹配尝试

让我们先尝试一个简单的想法来满足人们的偏好。一种方法是这次优先考虑男孩。我们尝试一个贪心策略:我们将尝试给每个男孩他可能做出的最佳选择。

我们从男孩1开始,给他他的第一选择——女孩C。我们让他们结婚,然后就不再考虑男孩1和女孩C了。现在我们有一个简化的问题:剩下4个男孩和4个女孩。

我们继续以这种贪心的方式为男孩们配对:接下来给男孩2他剩余选择中的最佳选择,即女孩A,让他们结婚。同样,男孩2和女孩A被排除在考虑之外。

我们继续这个过程,最终得到以下五对婚姻:

  • 男孩1 - 女孩C
  • 男孩2 - 女孩A
  • 男孩3 - 女孩D
  • 男孩4 - 女孩B
  • 男孩5 - 女孩E

现在,如果我们审视这组婚姻,会发现一个问题,这也正是推动我们研究稳定婚姻问题的动机。

男孩1娶了他的第一选择女孩C,他应该很高兴,但女孩C可能不高兴。同时,男孩4娶了女孩B。这里的一个困难是,如果我们查看偏好,女孩C对男孩4来说比女孩B更有吸引力。换句话说,男孩4喜欢别人的妻子胜过喜欢自己的妻子。

更糟糕的是,女孩C(别人的妻子)喜欢男孩4胜过喜欢她的丈夫(男孩1)。他们俩如果私奔,都会过得更好。无论他们是否真的私奔,他们都承受着巨大的压力。这使得这组婚姻不稳定


稳定匹配的核心概念

在一组婚姻中,如果一个男孩和一个女孩彼此喜欢对方胜过喜欢自己当前的配偶,他们就被称为一对私奔情侣,是不稳定的根源。

因此,稳定婚姻问题的目标是:看看我们是否能将所有人配对,并且没有私奔情侣。这样得到的就是一组稳定的婚姻。人们可能并不完全满意,但这没关系,因为他们永远找不到一个同样不满意、并且愿意和他们私奔从而让他们更幸福的人。所以它是稳定的。

事实证明,总是存在一种方法可以找到一组稳定的婚姻,甚至不止一种方法。


寻找稳定匹配的练*

以下是偏好列表的再次展示。你可以暂停视频,在纸上尝试,看看是否能想出一组男孩和女孩之间的稳定婚姻组合。

在课堂上,我们会实时进行这个练*:给5个不同的男孩一张女孩的偏好表,给5个不同的女孩一张男孩的偏好表。他们不应该告诉对方自己的偏好是什么,但女孩们应该面试男孩,男孩们同时面试女孩,试图达成婚约,看看他们最终形成的婚姻组合是否稳定。大多数时候他们确实能得到一组稳定的婚姻,但并非总是如此。这是一个有趣的练*,它也说明了我们将要介绍的寻找稳定婚姻的程序如果并行执行会非常有效。

无论如何,在这个特定的偏好集合中,我们至少可以找到两组稳定的婚姻。

最容易理解的一组是:所有女孩都得到了她们的第一选择。如果你查看图表,恰好所有女孩的第一选择男孩都不同。如果我们简单地给她们第一选择,没有女孩会想成为私奔情侣的一部分,因为她已经得到了第一选择。这绝对是稳定的。当然,这是一种非常特殊的情况,所有女孩的第一选择都不同(或所有男孩的第一选择都不同)是不常见的。但如果确实如此,你立刻就能得到一组稳定的婚姻。

另一组稳定的婚姻不那么明显,如下所示:

  • 男孩5 - 女孩A
  • 男孩1 - 女孩E
  • 男孩2 - 女孩B
  • 男孩3 - 女孩D
  • 男孩4 - 女孩C

你可以检查这些配对中没有不稳定性,这里没有私奔情侣。这是一组所谓的男孩最优婚姻。在这组婚姻中,每个男孩都得到了在所有可能的稳定婚姻中,他能得到的最佳配偶。没有一组稳定婚姻能让男孩5得到比女孩A更合意的女孩,也没有一组稳定婚姻能让男孩1得到比女孩E更合意的女孩。

令人遗憾的是,这对女孩们来说同时是最差的。也就是说,每个女孩都得到了在所有可能的稳定婚姻中,她们能得到的最差配偶。我们稍后会进一步探讨这一点。


稳定匹配的现实应用

这不仅仅是一个谜题。虽然它很有趣,是一个很好的谜题,但它远不止于此。

最初研究并发表这个问题的是Gale和Shapley在1962年的一篇论文。他们处理的是大学招生问题:学生对他们申请的大学有偏好排序,大学对申请他们的学生也有排序。我们试图在大学录取和学生偏好之间进行匹配。在那种情况下,大学发出录取通知,学生接受了,但后来学生又收到了更喜欢的学校的录取通知,于是改变主意、撤回接受,等等,这让所有人都抓狂——无论是管理者还是学生自己。大家的愿望是得到一个稳定的录取方案。Gale和Shapley提出了一种获得稳定婚姻的协议,可以应用于大学招生。

有趣的是,尽管Gale和Shapley因我们即将讨论的稳定婚姻解决方案而受到赞誉(他们是第一个发表的),但实际上,这个方案至少早20年就被一个全国性委员会发现并投入实践了,该委员会的工作是匹配实*医生和医院。即将开始临床培训(现代语言中称为住院医师)的医学院毕业生需要与医院匹配。住院医师有他们想去的首选医院,医院也有符合他们标准的住院医师排名。同样,问题是如何以稳定的方式将住院医师分配到医院。在他们发现这个稳定性算法之前,情况也是一团糟。

另一个真正的计算机科学应用由Tom Leighton(本教材的合著者,现为Akamai公司的CEO)描述。Akamai是一家拥有大量服务器(2010年约65,000台)的互联网基础设施公司,主要提供缓存的网页以便更快地本地响应。他们面临的问题是:如何将海量的网络请求(类似于“男孩”)分配给服务器(类似于“女孩”或“医院”),以便高效地完成任务。网络请求基于距离和服务器速度有偏好,服务器基于其位置和请求量也有偏好。事实证明,稳定婚姻方法为完成这种匹配提供了一种令人满意的方式。特别是由于涉及的数量非常庞大,我们即将描述的稳定婚姻仪式非常适合并行运行。

另一个出现的应用是匹配舞伴。大约十年前我教授这门课程时,一位合作讲师是印度舞蹈队的成员,她说她们可以用到这个方法。因为在舞蹈中同样有男孩和女孩舞伴,经常出现一个男孩更喜欢另一个男孩的舞伴,反之亦然的情况,然后他们开始重新配对,让其他人落单,导致关系紧张,成为团队中的破坏性来源。


总结

本节课中,我们一起学*了稳定匹配问题。我们首先通过一个贪心匹配的例子,看到了因“私奔情侣”导致的不稳定问题。然后,我们定义了稳定匹配的核心目标:找到一组没有私奔情侣的完美匹配。我们还了解到,对于任何给定的偏好列表,总是存在至少一个稳定匹配,并且存在“男孩最优”(同时是“女孩最差”)等特殊性质的匹配。最后,我们探讨了该问题在大学招生、医疗实*匹配、网络服务器分配乃至舞伴配对等多个现实领域的广泛应用,说明了这不仅仅是一个理论谜题,更是一个具有深远实践价值的算法问题。

计算机科学的数学基础:L2.11.2:匹配仪式

概述

在本节课中,我们将学*一个用于寻找稳定婚姻匹配的优雅算法,即“匹配仪式”。我们将详细描述这个仪式的步骤,并使用状态机、不变量和推导变量等概念来证明该算法总能终止,并产生一个稳定的婚姻匹配。

匹配仪式流程

上一节我们介绍了稳定婚姻问题。本节中我们来看看一个具体的求解算法——匹配仪式。这是一个按天进行的仪式,男孩和女孩共同参与。

以下是仪式每一天的具体步骤:

  1. 早晨:每个男孩查看自己的偏好列表,并向排在第一位的女孩“求婚”(或献唱小夜曲)。
  2. 下午:每个女孩审视所有向她求婚的男孩,拒绝除她最喜欢的那位之外的所有人。
  3. 晚上:被拒绝的男孩将拒绝他的女孩从自己的偏好列表中划掉。

第二天早晨,仪式重复进行,但男孩们将向各自更新后的列表中的第一位女孩求婚。

这个过程会一直持续,直到某一天没有任何变化发生。根据定义,当每个女孩最多只有一位求婚者时,仪式停止。在这一天,每个女孩将与她唯一的求婚者结婚。我们声称这样产生的婚姻是稳定的。

仪式作为状态机

如果我们思考这个过程,它本质上是一个状态机。状态就是每个早晨男孩们的偏好列表集合。晚上的“划掉”操作后,状态会演变为第二天早晨的新列表。我们可以运用状态机的概念来分析它。

我们的证明任务分为两部分:

  1. 证明这个状态机终止,即存在一个“婚礼日”。
  2. 证明这个状态机是部分正确的,即当机器停止时,每个人都已结婚,并且婚姻是稳定的。

证明终止性

终止性的证明很简单。状态是每个早晨男孩列表上剩余的名字总数。由于男孩被拒绝后会划掉女孩的名字,这个总数是一个严格递减的非负整数值变量。

根据良序原理,这个严格递减的变量必然会达到一个最小值。根据定义,当它达到最小值时,算法必须停止,因为它无法再递减。因此,必然存在一个婚礼日。

证明正确性

现在我们来检查这个程序的正确性,分析婚礼日会发生什么。我们需要证明每个人都结婚了,并且婚姻是稳定的。为此,我们将观察一些推导变量和一个关键的不变量。

第一个观察:女孩的处境逐日改善(或至少不会变差)。对于任何给定的女孩,她明天的“最爱”(即向她求婚者中她最喜欢的)至少会和今天的一样好。原因在于,今天的“最爱”会持续向她求婚,直到他被拒绝;而他只会在女孩得到一个更好的求婚者时才会被拒绝。

用状态机的语言来说,女孩“最爱”的排名(在她自己的偏好列表中的位置)是一个弱递增变量

第二个观察:男孩的处境逐日变差(或至少不会变好)。一个男孩明天的求婚对象不会比今天的更称心。如果他没被拒绝,明天会继续向同一位女孩求婚;如果被拒绝了,他将转向列表中排名更低(即不那么喜欢)的女孩。

因此,男孩求婚对象的排名(在他自己偏好列表中的位置)是一个弱递减变量

这些观察引出了匹配仪式的一个关键不变量。

关键不变量

这个不变量表述如下:
对于任意女孩 G 和任意男孩 B,如果 G 不在 B 的列表中(即 G 曾被 B 划掉),那么女孩 G 拥有的“最爱”比男孩 B 更优。

原因:当 G 拒绝 B 时,她就已经有了一个比 B 更好的求婚者。根据女孩“最爱”排名弱递增的性质,她的求婚者会一直保持比 B 更好。因此,对于任何其列表上已没有 G 的男孩 BG 总会有一个她更喜欢于 B 的求婚者。

这个性质在仪式的每一天都成立。

婚礼日的分析

现在,我们利用这个不变量来分析婚礼日,证明每个人都已婚且婚姻稳定。

首先,证明每个人都已婚。根据婚礼日的定义,每个女孩最多有一位求婚者。我们需要证明每个男孩也都结婚了。

一个男孩要么已婚(因为他正在向他列表首位的女孩求婚),要么他的列表上所有女孩都已被划掉,从而没有求婚对象。这是他不结婚的唯一可能情况。

证明采用反证法。假设存在一个男孩 B 没有结婚。这等价于他的偏好列表为空(否则他会向某人求婚并可能结婚)。如果他的列表为空,根据上述不变量,每个女孩都有一个她比喜欢 B 更喜欢的求婚者,这意味着每个女孩都将与一个她认为比 B 更好的人结婚。

由于男孩和女孩数量相同,且不存在重婚(一夫多妻或一妻多夫),所有男孩都必须结婚。这与存在未婚男孩 B 的假设矛盾。因此,在婚礼日每个人都已婚。

其次,证明婚姻是稳定的。我们需要证明不存在“私奔对”。考虑任意一个男孩 Bob,我们断言他不会与任何女孩构成私奔对。分两种情况讨论,两者都直接由不变量得出:

  1. 对于仍在 Bob 最终列表上的任何女孩 GBob 已经与他自己列表上最靠前的女孩结婚。因此,他不会为了列表上其他女孩而想要私奔。
  2. 对于不在 Bob 最终列表上的任何女孩 G:根据不变量,G 已经与一个她比喜欢 Bob 更喜欢的人结婚。因此,G 不会愿意与 Bob 私奔。

由于 Bob 是任意男孩,以上论证表明没有男孩会处于私奔对中。因此,产生的所有婚姻都是稳定的。

总结

本节课中,我们一起学*了用于解决稳定婚姻问题的“匹配仪式”算法。我们详细描述了其按天进行的步骤,并将其建模为一个状态机。通过分析男孩列表总长度这一严格递减的推导变量,我们证明了算法必然终止。更重要的是,我们发现并利用了一个关键不变量——被男孩划掉的女孩,总拥有一个比该男孩更优的求婚者。基于这个不变量,我们证明了在算法终止的婚礼日,每个人都能够结婚,并且最终形成的所有婚姻都是稳定的。这个优雅的算法展示了如何运用不变量和状态机思想来清晰地证明算法的正确性。

计算机科学的数学基础:L2.11.5:最优稳定匹配 🎯

在本节课中,我们将要学*稳定婚姻问题中的一个重要概念——最优稳定匹配。我们将探讨在交配仪式中,男孩和女孩各自获得的配偶质量,并证明该算法为所有男孩同时找到了他们可能的最佳稳定配偶。

上一节我们介绍了稳定婚姻的概念及其价值。本节中我们来看看,在交配仪式中,参与者们最终获得的配偶质量如何。

概述:最优配偶的定义

首先,我们需要定义一个关键概念:最佳可能配偶。对于一个男孩基思而言,在所有他能以稳定方式结婚的女性中,排名最高的那位女性妮可,就被称为基思的最佳可能配偶。这意味着,在所有可能的稳定婚姻方案中,妮可是基思能娶到的最理想的妻子。

核心主张:男孩最优与女孩最差

交配仪式产生了一个特定的稳定婚姻匹配。我们提出的核心主张是:这个匹配对所有的男孩来说同时是最优的。也就是说,每个男孩都娶到了他所有可能稳定配偶中的最佳人选。

这听起来有些不同寻常,因为通常优化一个人的利益会牺牲其他人的利益。但在这个算法中,所有男孩都同时达到了他们的最优状态。相应地,一个悲观的结论是:所有的女孩都得到了她们在所有可能的稳定婚姻中,可能得到的最差配偶

证明:男孩最优性

让我们来证明交配仪式导致男孩最优的婚姻。我们将使用反证法。

  1. 假设存在矛盾:假设妮可是男孩基思的最佳可能配偶,但在某次交配仪式的结果中,基思并没有和妮可结婚。
  2. 推导矛盾点:既然妮可是最佳可能配偶,而基思没有娶她,那么基思一定是娶了一个他认为不如妮可受欢迎的女孩。这意味着在仪式过程中的某一天,基思被妮可拒绝了,并将她从自己的名单上划掉。我们把这一天称为基思的“糟糕日”。
  3. 寻找最早的“糟糕日”:在所有男孩中,必然有一个最早经历“糟糕日”的男孩。我们不妨假设这个男孩就是基思。
  4. 分析“糟糕日”当天:在基思的糟糕日,妮可因为有了一个更喜欢的追求者汤姆而拒绝了基思。因此我们知道:
    • 公式妮可偏好:汤姆 > 基思
  5. 利用“最早”的性质:因为基思的糟糕日是所有人中最早的,所以汤姆此时还没有经历过糟糕日(即还没有划掉自己的最佳可能配偶)。这意味着,汤姆当时正在追求的妮可,至少和他自己的最佳可能配偶一样好(甚至更好)。
    • 公式汤姆偏好:妮可 ≥ 汤姆的最佳可能配偶
  6. 构造不稳定对:现在考虑一个假设的稳定婚姻方案,其中妮可嫁给了基思(因为妮可是基思的最佳可能配偶,这样的方案应该存在)。在这个方案中,汤姆会与某人结婚(可能是他的最佳可能配偶,也可能不是)。但根据我们上面的分析:
    • 妮可更喜欢汤姆(而不是基思)。
    • 汤姆认为妮可至少和他的配偶一样好。
    • 这意味着妮可和汤姆构成了一个私奔对,破坏了该婚姻方案的稳定性。
  7. 得出矛盾:这与“存在一个妮可嫁给基思的稳定婚姻方案”的假设矛盾。因此,最初的假设(基思在交配仪式中没有娶到妮可)是错误的。所以,基思在交配仪式中必然娶到了他的最佳可能配偶妮可

类似的、且更简单的论证可以表明,交配仪式也让所有女孩得到了她们最差的可能稳定配偶

延伸问题与讨论

这个结论引出了一系列有趣的问题:

以下是关于其他稳定匹配可能性的问题:

  • 除了交配仪式产生的匹配,还有其他可能的稳定婚姻吗?答案是肯定的。一个简单的方法是交换男孩和女孩的角色重新进行仪式,这样会产生一个对女孩最优、对男孩最差的稳定匹配。
  • 是否存在既不是男孩最优也不是女孩最优的其他稳定匹配?一般来说,可能存在指数级数量的稳定婚姻。
  • 如何在这些不同的稳定匹配中做出“更好”或“更公*”的选择?

以下是关于参与者策略的问题:

  • 撒谎是否有益?既然男孩已经获得了最优结果,他们撒谎无法获得更好收益。但女孩可以通过合谋撒谎,来迫使交配仪式产生一个对女孩最优的稳定匹配。这引出了是否存在能防止撒谎的协议等问题。

这些深入的问题我们不再展开,但它们展示了稳定婚姻理论丰富的内涵。如果你想了解更多,可以参考Gusfield和Irving的相关著作。

总结

本节课中我们一起学*了稳定婚姻问题中的最优稳定匹配概念。我们证明了经典的交配仪式(Gale-Shapley算法) 会产生一个独特的稳定匹配,其性质是:

  • 对男孩最优:每个男孩都获得了他所有可能稳定配偶中的最佳人选。
  • 对女孩最差:每个女孩都获得了她所有可能稳定配偶中的最差人选。

这个结论揭示了算法中隐含的倾向性,并为进一步研究不同稳定匹配的性质和参与者的策略行为奠定了基础。

计算机科学的数学基础:L2.11.7:二部图匹配 🧩

在本节课中,我们将要学*二部图匹配问题。这是一个在图论中非常重要的问题,它可以帮助我们理解如何将两组不同的对象进行有效配对。我们将从稳定匹配问题出发,引出二部图匹配的一般定义,并探讨匹配存在的条件。

二部图与匹配问题

上一节我们介绍了稳定匹配问题,它是二部匹配问题的一个具体例子。本节中我们来看看二部匹配问题的一般设置。

二部匹配问题的场景是:你有一个简单的图,其顶点被分成两组。就像在稳定匹配问题中一样,我们可以称这两组为女孩(G)和男孩(B)。

二部图的定义如下:它是一个图,其中顶点被分为两组不相交的集合,称为左顶点和右顶点。每个顶点要么属于左集,要么属于右集。图中的边只存在于左顶点和右顶点之间。

在匹配问题中,我们有一个规范:每个女孩都愿意与某些男孩配对,但不是所有男孩。我们可以通过添加边来表示这种意愿。例如,如果第一个女孩愿意与第二个男孩和最后一个男孩配对,那么图中就会有从她指向这两个男孩的边。因此,边代表了女孩和男孩之间的兼容性。

匹配的目标与定义

对女孩和男孩进行匹配的限制是:我们试图让所有女孩都与一个独特的、兼容的男孩配对。也就是说,每个女孩都被分配一个独特的、与她兼容的男孩。

以下是一个匹配的例子,其中每个女孩都通过一条突出的洋红色边连接到一个不同的男孩:

我们正式地想要一个从女孩到男孩的双射(一一对应),并且这个对应关系要遵循图中的边。

匹配的瓶颈

让我们看一个找不到匹配的案例。假设我们移除了上图中的一条边。

现在,我们发现最后一个女孩无法与第二个男孩(即我们之前匹配给她的男孩)配对了。让我们尝试寻找其他匹配方案,但发现不存在任何匹配。

原因是:如果你看左边的三个女孩,再看右边所有与她们兼容的男孩,你会发现这三个女孩总共只与两个男孩兼容。这意味着只有两个男孩可供三个女孩分享,这就是所谓的“瓶颈”。

更一般地说,如果你有一组左边的女孩集合 S,那么 S 在边关系下的“像”记作 E(S),它是所有与 S 中至少一个女孩兼容的男孩的集合。

在我们之前的例子中,S 的大小是 3,而 E(S) 的大小是 2。因为 3 > 2,所以我们遇到了瓶颈,不可能找到匹配。

瓶颈的定义是:如果存在一个左边的女孩集合 S,使得 |S| > |E(S)|,那么就存在一个瓶颈。

我们可以做的第一个观察是“瓶颈引理”:如果一个瓶颈存在(即存在集合 S 使得 |S| > |E(S)|),那么匹配是不可能的。原因很明显,因为女孩的数量超过了她们共同兼容的男孩数量。

霍尔定理

现在,一个相当深刻的定理是,反过来也成立:如果没有瓶颈,那么就一定存在一个匹配。这就是著名的霍尔定理

霍尔定理的表述是:在一个二部图中,存在一个覆盖所有左顶点的匹配,当且仅当对于左顶点的每一个子集 S,都有 |E(S)| ≥ |S|

这个结论并不那么显而易见,但我们可以找到一个易于理解的证明。

总结

本节课中我们一起学*了二部图匹配问题。我们首先回顾了稳定匹配问题作为二部匹配的特例,然后给出了二部图和匹配的正式定义。我们探讨了导致匹配不可能的“瓶颈”现象,并最终引出了保证匹配存在的关键定理——霍尔定理。理解瓶颈条件和霍尔定理是解决许多实际配对问题的基础。

计算机科学的数学基础:L2.11.9:霍尔定理 🧩

在本节课中,我们将学*图论中的一个核心定理——霍尔定理。该定理为判断二分图中是否存在完美匹配提供了一个充要条件。我们将从定义开始,逐步理解定理的陈述、一个实用的充分条件,并最终探讨其证明思路。

二分图与匹配的正式定义

上一节我们介绍了二分图在“男孩-女孩”配对问题中的直观背景。现在,我们将其形式化。

一个二分图 H 包含两个互不相交且非空的顶点集合:左顶点集 L(H) 和右顶点集 R(H)。图 H 的所有边都只连接 L(H) 中的顶点和 R(H) 中的顶点。

在二分图中,一个匹配(或完美匹配)是一个从 L(H)R(H)全单射函数 M。这意味着:

  • 全射性L(H) 中的每一个顶点(女孩)都有一个匹配对象 M(L),该对象位于 R(H)(男孩)中。
  • 单射性:没有两个左顶点匹配到同一个右顶点。
  • 遵循边:对于每个左顶点 l,边 (l, M(l)) 必须是图 H 中实际存在的一条边。用数学语言描述,即匹配函数 M 的图是 H 的边集的一个子集。

霍尔定理的陈述

有了以上定义,我们可以正式陈述霍尔定理,而无需提及男孩和女孩。

霍尔定理:对于一个二分图 H,如果对于左顶点集 L(H)每一个子集 S,都满足以下霍尔条件(或称“无瓶颈条件”):
|S| ≤ |N(S)|
其中 N(S)S 中所有顶点在图 H 中的邻居集合(即与 S 中任意顶点相连的右顶点集合)。
那么,图 H 中就存在一个从 L(H)R(H) 的完美匹配。

简而言之:当且仅当不存在“瓶颈”集合时,完美匹配存在。

一个实用的充分条件:度约束图

直接验证霍尔条件需要检查左顶点集的所有子集,这在计算上是困难的(指数级复杂度)。不过,存在一个常见且易于验证的充分条件。

如果一个二分图 H 满足以下度约束条件

  • 每个左顶点(女孩)的度(喜欢的男孩数)至少d
  • 每个右顶点(男孩)的度(被喜欢的次数)至多d
    那么,该图一定满足霍尔条件,从而存在完美匹配。

证明如下

  1. 任取一个左顶点子集 S
  2. S 出发的边总数 E 满足:d * |S| ≤ E(因为每个左顶点至少有 d 条边)。
  3. 所有这些边都指向 N(S) 中的顶点。由于每个右顶点至多有 d 条边,因此 E ≤ d * |N(S)|
  4. 结合以上两点,得到 d * |S| ≤ d * |N(S)|
  5. 两边同时除以 d,得到 |S| ≤ |N(S)|
  6. 由于 S 是任意选取的,霍尔条件成立。

因此,度约束条件是霍尔条件的一个充分条件,它保证了完美匹配的存在。请注意,这不是必要条件;许多存在完美匹配的图并不满足度约束。

霍尔定理的证明思路

现在,我们来探讨霍尔定理本身的证明。证明的核心思想是强归纳法:假设定理对顶点数较少的所有二分图成立,来证明它对当前图也成立。证明分为两种情况。

情况一:存在一个“恰好饱和”的真子集
假设存在一个非空且非全集的左顶点子集 S,使得 |S| = |N(S)|。这是一个关键情况。

  • 可以证明,在原图没有瓶颈的条件下,由 SN(S) 诱导出的子图,以及由剩余顶点 L\SR\N(S) 诱导出的子图,也都满足霍尔条件(即没有瓶颈)。
  • 由于这两个子图的规模都小于原图,根据归纳假设,它们内部各自存在完美匹配。
  • 将这两个子图的匹配合并起来,就得到了原图的一个完美匹配。

情况二:所有真子集都“严格更小”
假设对于所有非空且非全集的左顶点子集 S,都有 |S| < |N(S)|

  • 此时,我们可以任意选取一个左顶点 g 和她的一个邻居 b 进行匹配。
  • gb 从图中移除。由于之前所有子集 S 的邻居集大小都严格大于 S 本身,移除一个顶点后,剩余图依然满足霍尔条件。
  • 剩余图的顶点数减少,根据归纳假设,存在完美匹配。
  • (g, b) 这对匹配加回去,就得到了原图的完美匹配。

通过以上两种情况的讨论,我们完成了对霍尔定理的归纳证明。

总结

本节课中我们一起学*了:

  1. 霍尔定理的正式定义:完美匹配存在的充要条件是对于左部的所有子集 S,其邻居集大小不小于 S 本身的大小(|S| ≤ |N(S)|)。
  2. 一个实用的充分条件:如果二分图是度约束的(每个左顶点度≥d,每个右顶点度≤d),则完美匹配必然存在。这为快速判断许多场景下的匹配存在性提供了便利。
  3. 定理的证明思路:证明采用了强归纳法,通过分析图中是否存在一个大小等于其邻居集大小的真子集,将问题分解为两个更小的子问题或直接构造匹配,从而完成证明。

霍尔定理是组合数学与图论中一个优美而强大的工具,它在任务分配、调度、网络流等众多计算机科学领域有着广泛的应用。

计算机科学的数学基础:L3.1.1:算术和 📊

在本节课中,我们将要学*计数与组合学的基础知识。当我们进行计数时,常常需要将一系列数字相加。因此,掌握如何高效地求和至关重要。本节课,我们将从最简单的求和类型——算术和开始。

算术和的起源故事 📖

算术和有一个著名的历史故事。在18世纪,一位老师为了让学生们在课堂上保持忙碌,提出了一个求和问题:计算从89开始,以13为公差递增的30个数字的总和。

伟大的数学家卡尔·弗里德里希·高斯在九岁时就展现了他的天赋。据说他当时就发现了快速计算此类和的方法,而没有像其他同学一样进行繁琐的逐项相加。

算术和的通用公式推导 🔍

上一节我们介绍了算术和的背景,本节中我们来看看如何推导其通用求和公式。

假设我们有一个算术序列:

  • 第一项为 f
  • 公差为 d
  • 最后一项为 l
  • 总项数为 n

那么,这个序列的和 A 可以表示为:

A = f + (f + d) + (f + 2d) + ... + l

高斯的关键技巧是将这个和倒序书写:

A = l + (l - d) + (l - 2d) + ... + f

现在,将这两个等式相加:

2A = (f + l) + (f + l) + (f + l) + ... + (f + l)

因为总共有 n 项,所以等式右边是 n(f + l) 的和。因此:

2A = n * (f + l)

由此,我们得到算术和的通用公式:

A = n * (f + l) / 2

这个公式可以理解为:总和 = 项数 × (首项 + 末项) / 2。其中 (首项 + 末项) / 2 恰好是整个序列的*均值。所以,算术和也等于项数乘以序列的*均值

经典示例:从1到n的整数和 🧮

现在,让我们应用这个公式来解决一个最经典的算术和问题:求从1到n的所有整数之和。

在这个序列中:

  • 首项 f = 1
  • 末项 l = n
  • 项数 n = n (注意:这里的n既是项数,也代表末项的值)

根据我们的公式:

总和 = n * (1 + n) / 2

用代码表示这个公式可以是:

def sum_of_integers(n):
    return n * (1 + n) // 2

这就是著名的求和公式。例如,1到100的和是 100 * 101 / 2 = 5050


本节课中我们一起学*了算术和。我们了解了它的历史背景,推导了其通用求和公式 A = n * (f + l) / 2,并应用该公式解决了从1到n求和的经典问题。掌握这个公式是学*后续更复杂求和与计数技巧的重要基础。

计算机科学的数学基础:L3.1.3:几何和 📐

在本节课中,我们将要学*几何和与几何级数。我们将了解它们的定义、推导其封闭形式的公式,并探讨一个在金融领域(如计算货币未来价值)的典型应用。

上一节我们介绍了算术和,其中每一项都比前一项大一个固定的加量。本节中我们来看看另一种重要的和——几何和,其中每一项都是前一项的固定倍数。这种和在许多不同的环境中都会出现。

几何和的定义与推导

几何和的标准形式如下:

公式:
[
G_n = 1 + x + x^2 + \dots + x^n = \sum_{k=0}^{n} x^k
]

注意,1 可以看作是 (x^0)。我们的目标是找到一个不包含省略号“...”的、关于项数 (n) 的封闭形式表达式。

推导算术和公式时,我们使用了颠倒相加的技巧。对于几何和,我们将使用一种称为扰动法的技巧。其核心思想是:将总和 (G_n) 乘以公比 (x),然后观察它与原式的关系。

推导过程:

  1. 将 (G_n) 乘以 (x):
    [
    x \cdot G_n = x + x^2 + x^3 + \dots + x^{n+1}
    ]
  2. 用原式 (G_n) 减去这个新式子:
    [
    G_n - x \cdot G_n = (1 + x + x^2 + \dots + x^n) - (x + x^2 + \dots + x^{n+1})
    ]
  3. 观察等式右边,从 (x) 到 (x^n) 的所有项都相互抵消了,只剩下第一项 1 和最后一项 (-x^{n+1}):
    [
    G_n - xG_n = 1 - x^{n+1}
    ]
  4. 提取公因式 (G_n),并求解:
    [
    G_n(1 - x) = 1 - x^{n+1}
    ]
    [
    G_n = \frac{1 - x^{n+1}}{1 - x}
    ]

这样,我们就得到了几何和的封闭形式公式。这个推导过程清晰地展示了“聪明人”是如何发现这个公式的。

从几何和到几何级数

当我们考虑无限项相加时,就得到了几何级数

公式:
[
S = 1 + x + x^2 + x^3 + \dots = \sum_{i=0}^{\infty} x^i
]

无限和定义为前 (n) 项部分和 (G_n) 在 (n) 趋于无穷大时的极限(假设该极限存在)。

推导过程:

  1. 根据几何和的公式,部分和 (G_n = \frac{1 - x^{n+1}}{1 - x})。
  2. 几何级数 (S) 是 (G_n) 的极限:
    [
    S = \lim_{n \to \infty} G_n = \lim_{n \to \infty} \frac{1 - x^{n+1}}{1 - x}
    ]
  3. 当 (|x| < 1) 时,随着 (n) 增大,(x^{n+1}) 会趋*于 0。
  4. 因此,在 (|x| < 1) 的条件下,我们得到:
    [
    S = \frac{1}{1 - x}
    ]

这个公式比有限几何和的公式更加简洁。

应用:货币的未来价值 💰

几何和在金融领域有直接的应用,例如评估货币在不同时间点的价值。其核心原理基于一个假设:资金可以存入银行获得无风险利息。

基本概念:

  • 设银行年利率为 3%,则银行利率因子 (b = 1.03)。这意味着现在存入 1 美元,一年后将变为 (b) 美元。
  • 反过来,为了在一年后获得 1 美元,现在需要存入的金额称为现值。设现值为 (r) 美元,则有 (b \cdot r = 1),解得 (r = 1/b)。这里 (r) 就是折现因子

公式:

  • (k) 年后支付的 (m) 美元,其今天的现值是 (m \cdot r^k),其中 (r = 1/b)。

年金估值示例

年金是一种金融合约:投保人现在支付一笔保费,以换取未来一系列定期收入。让我们分析一个具体例子:

问题: 我(保险公司)承诺在未来10年内,每年末支付给你100美元。假设年利率固定为3%,你现在应该支付多少保费 (Y) 才公*?

分析:

  • 第1年末的100美元,现值 = (100 \cdot r^1)
  • 第2年末的100美元,现值 = (100 \cdot r^2)
  • ...
  • 第10年末的100美元,现值 = (100 \cdot r^{10})

公*的保费 (Y) 应等于所有这些现值之和:
[
Y = 100r + 100r^2 + \dots + 100r^{10} = 100r (1 + r + r^2 + \dots + r^9)
]

括号内是一个几何和,公比为 (r),项数为10(从 (r^0) 到 (r^9))。应用几何和公式:

计算:
[
Y = 100r \cdot \frac{1 - r^{10}}{1 - r}
]
代入 (b=1.03, r=1/b \approx 0.9709),进行计算:
[
Y \approx 100 \times 0.9709 \times \frac{1 - 0.9709^{10}}{1 - 0.9709} \approx 853.02
]

因此,这份年金的公*保费约为 853.02 美元。虽然未来支付总额是1000美元,但由于货币的时间价值,其当前价值更低。

思考: 如果签订合约后,银行利率上升到5%(即 (r) 变小),这份合约对谁更有利?答案是支付保费的你。因为计算现值时使用的折现因子变小了,未来支付的100美元“更不值钱”了,这意味着保险公司(我)当初收取的853.02美元保费,相对于新的利率环境显得过高了,所以你占了便宜。


本节课中我们一起学*了:

  1. 几何和的定义及其封闭形式公式:(G_n = \frac{1 - x^{n+1}}{1 - x}),并通过扰动法推导了它。
  2. 几何级数在 (|x| < 1) 条件下的求和公式:(S = \frac{1}{1 - x})。
  3. 几何和的一个典型应用:利用折现因子 (r) 计算货币的未来价值,并以此分析了年金的公*定价问题。

计算机科学的数学基础:L3.1.5:书本堆叠问题 📚

在本节课中,我们将学*一种在计算机科学中频繁出现的求和类型——调和和。我们将通过一个具体的例子来探讨它:如何将一堆书本堆叠在桌子边缘,并使其尽可能向外延伸而不掉落。


概述

我们将从最简单的情况开始分析,逐步推导出使用 n 本书时能达到的最大悬垂距离。这个过程将自然地引出调和数的概念。我们将看到,最大悬垂距离 B_n 与调和数 H_n 直接相关,其公式为 B_n = (1/2) * H_n


单本书的情况

首先,我们考虑最简单的情况:只有一本书。

假设书本是均匀的,长度为1单位。其质心位于书本的正中央,即距离两端各 1/2 的位置。为了使书本在桌子边缘保持*衡而不掉落,书本的质心必须恰好位于桌子边缘的正上方。因此,一本书能伸出的最大距离是 1/2

由此,我们得到单本书的悬垂公式:
B_1 = 1/2


n 本书到 n+1 本书

上一节我们介绍了单本书的*衡原理。本节中,我们来看看如何递归地构建一个更大的稳定书堆。

假设我们已经知道如何将 n 本书堆叠成一个稳定的结构(即其整体质心位于支撑点上方)。现在,我们想在第 n 本书的下方再添加一本书(第 n+1 本),并使整个新堆叠的悬垂距离最大化。

关键思路如下:

  1. 整个 n+1 本书堆叠的质心必须位于桌子边缘,这是获得最大悬垂的条件。
  2. 顶部的 n 本书作为一个整体,其质心必须位于底部那本书(第 n+1 本)的右边缘,这样才能在底部书本上获得最大延伸。
  3. 底部书本自身的质心在其中心,距离其右边缘 1/2

因此,问题转化为:顶部 n 本书(质心在底部书本右边缘)和底部一本书(质心在其中心)如何在桌子边缘达到*衡?这就像一个杠杆,两端重量分别为 n1,支点(桌子边缘)位于它们之间。

Δ 为从顶部 n 本书的质心到整个 n+1 本书质心(即桌子边缘)的距离。根据杠杆*衡原理(力矩相等),我们有:
n * Δ = 1 * (1/2 - Δ)

解这个方程:
nΔ = 1/2 - Δ
nΔ + Δ = 1/2
Δ(n + 1) = 1/2
Δ = 1 / (2(n + 1))

这个 Δ 就是增加一本书所带来的悬垂增量。


悬垂距离的通项公式

根据上面的推导,我们可以建立悬垂距离 B_n 的递归关系。

已知:
B_1 = 1/2
B_{n+1} = B_n + Δ = B_n + 1/(2(n+1))

将这个递归式展开:
B_n = 1/2 + 1/(2*2) + 1/(2*3) + ... + 1/(2*n)
B_n = (1/2) * (1 + 1/2 + 1/3 + ... + 1/n)

括号内的求和 1 + 1/2 + 1/3 + ... + 1/n 被称为第 n调和数,记作 H_n

因此,n 本书能达到的最大悬垂距离公式为:
B_n = (1/2) * H_n


核心概念总结

以下是本节课的核心公式与概念:

  • 单本书悬垂B_1 = 1/2
  • 悬垂增量:添加第 n+1 本书时,悬垂增加 Δ = 1/(2(n+1))
  • 递归关系B_{n+1} = B_n + 1/(2(n+1))
  • 调和数H_n = 1 + 1/2 + 1/3 + ... + 1/n
  • 通项公式n 本书的最大悬垂 B_n = (1/2) * H_n

总结

本节课中,我们一起学*了书本堆叠这一经典问题。我们从简单的物理*衡原理出发,通过递归的思想,推导出了使用 n 本书时能获得的最大悬垂距离公式。这个公式揭示了一个有趣的现象:最大悬垂距离与调和数 H_n 成正比。虽然调和数随着 n 增大会增长,但增长非常缓慢(对数级),这意味着即使堆叠很多书,悬垂距离的增长也极其有限。这个例子巧妙地展示了递归思维和调和和在分析算法与结构问题中的应用。

计算机科学的数学基础:P70:L3.1.7 - 积分法 📐

在本节课中,我们将学*如何使用积分法来估计和计算调和数。我们将通过一个有趣的“书本堆叠”问题引入,并推导出调和数的上下界,最终理解渐*等价的概念。


问题引入:书本堆叠

上一节我们讨论了书本堆叠问题。我们发现,当有 N 本书时,最上层书的悬垂距离是调和和的一半。这个调和和 H_N 定义为:

H_N = 1 + 1/2 + 1/3 + ... + 1/N

问题在于,没有简单的公式能精确计算这个和。但是,我们可以使用积分法来得到一个非常准确的估计。

使用积分法求下界

为了估计 H_N,我们将其与一个积分进行比较。

想象一系列宽度为1的矩形,第一个矩形高度为1,第二个为1/2,第三个为1/3,以此类推。这些矩形的总面积就等于我们想求的调和数 H_N

我们关心 H_N 的下界,因为它能告诉我们至少需要多少本书才能达到某个悬垂距离。为了找到下界,我们观察一条穿过矩形左上角的曲线 y = 1/(x+1)

这条曲线严格位于所有矩形的下方。因此,曲线 y = 1/(x+1)0N 下方的面积,就是矩形总面积(即 H_N)的一个下界。

计算这个积分:

∫(0 to N) 1/(x+1) dx = ln(N+1)

因此,我们得到下界:

H_N > ln(N+1)

这个下界告诉我们,要使悬垂距离达到3本书的长度(即 H_N >= 6),需要满足 ln(N+1) >= 6。解这个不等式,得到 N >= e^6 - 1 ≈ 403。这意味着,理论上大约需要403本书。

实际应用与上界推导

在实际实验中,使用较轻且坚硬的物体(如CD盒)可以更好地验证这个模型。一个由43个CD盒堆成的塔,其顶层可以伸出桌子边缘约1.8到1.9个盒子的长度,这与我们的理论预测相符。

接下来,我们用类似的逻辑推导 H_N 的上界。这次,我们观察一条穿过矩形右上角的曲线 y = 1/x

这条曲线严格位于所有矩形的上方。因此,曲线 y = 1/x1N 下方的面积,就是 H_N 的一个上界。

计算这个积分:

∫(1 to N) 1/x dx = ln(N)

同时,我们需要加上第一个矩形的高度 1。因此,我们得到上界:

H_N < 1 + ln(N)

综合上下界与渐*等价

结合我们得到的上下界,可以将调和数 H_N 约束在以下范围内:

ln(N+1) < H_N < 1 + ln(N)

随着 N 增大,ln(N+1)1 + ln(N) 的值会越来越接*。这意味着,H_N 的增长行为主要由 ln(N) 主导。

在数学中,我们用渐*等价(Asymptotic Equivalence)来描述这种关系,记作 ~。其精确定义为:

f(N) ~ g(N)  当且仅当   lim (N→∞) [f(N) / g(N)] = 1

因此,我们可以说:

H_N ~ ln(N)

这意味着当 N 非常大时,H_N *似等于 ln(N),低阶项的影响可以忽略。

积分法的一般形式

让我们总结一下积分法的一般步骤。假设 f(x) 是一个正的、单调递减的函数。

定义:

  • S = f(1) + f(2) + ... + f(N) (我们想求的和)
  • I = ∫(1 to N) f(x) dx (对应的积分)

那么,我们可以得到和的上下界:

I + f(N) <= S <= I + f(1)

这个定理为我们提供了一种通用的、通过积分来估计求和的方法。


总结

本节课中,我们一起学*了积分法。我们从书本堆叠问题出发,通过将求和与积分比较,推导出了调和数 H_N 的上下界,并得出结论:H_N 渐*等价ln(N)。最后,我们概括了积分法对于单调递减函数求和估计的一般形式。掌握这个方法,对于分析算法复杂度等领域中的求和问题非常有帮助。

计算机科学的数学基础:L3.1.9:斯特林公式 📊

在本节课中,我们将学*如何估算乘积,特别是n的阶乘(n!)。我们将通过取对数将乘积转化为求和,并利用积分方法,最终推导出估算n!的著名公式——斯特林公式。

从乘积到求和 🔄

估算乘积的一种通用方法是先取对数,将其转化为求和问题。对于n的阶乘,其定义为前n个正整数的乘积:

公式: n! = 1 × 2 × ... × (n-1) × n

在乘积符号中,可以表示为:

公式: n! = ∏_{i=1}^{n} i

为了估算这个乘积,我们首先计算其自然对数:

公式: ln(n!) = ln(1) + ln(2) + ... + ln(n) = ∑_{i=1}^{n} ln(i)

现在,我们的目标变成了估算这个求和式。

应用积分方法 📐

上一节我们介绍了积分方法,本节中我们来看看如何用它来估算对数求和。我们关注函数 f(x) = ln(x),这是一个在正实数域上单调递增的函数。

根据积分方法定理,对于一个单调递增函数 f,其求和 S = ∑_{i=1}^{n} f(i) 满足以下不等式:

公式: ∫_{1}^{n} f(x) dx + f(1) ≤ S ≤ ∫_{1}^{n} f(x) dx + f(n)

f(x) = ln(x) 代入,我们得到:

公式: ∫_{1}^{n} ln(x) dx ≤ ∑_{i=1}^{n} ln(i) ≤ ∫_{1}^{n} ln(x) dx + ln(n)

接下来,我们需要计算这个积分。根据微积分知识,ln(x) 的不定积分为:

公式: ∫ ln(x) dx = x ln(x) - x + C

因此,定积分的计算结果为:

公式: ∫_{1}^{n} ln(x) dx = [x ln(x) - x]_{1}^{n} = n ln(n) - n + 1

将这个结果代回不等式,我们得到对数求和的边界:

公式: n ln(n) - n + 1 ≤ ln(n!) ≤ n ln(n) - n + 1 + ln(n)

推导斯特林公式(启发式)🧪

上面的边界已经相当紧凑。为了得到一个更简洁的*似,我们可以取上下界的“中间值”。一种启发式的做法是,将 ln(n!) *似为积分值加上边界项 ln(n) 的一半:

公式: ln(n!) ≈ n ln(n) - n + (1/2) ln(n)

现在,我们对等式两边取指数(以e为底),将求和转换回乘积:

公式: n! ≈ e^{n ln(n) - n + (1/2) ln(n)} = e^{ln(n^n)} * e^{-n} * e^{ln(√n)} = n^n * e^{-n} * √n

由此,我们得到一个初步的*似公式:

公式: n! ≈ √n * (n/e)^n

这个启发式推导虽然不严格,但给出了一个非常接*真实值的估计。

精确的斯特林公式 🎯

实际上,存在一个更精确的渐*公式来描述n的阶乘,这就是著名的斯特林公式

公式: n! ~ √(2πn) * (n/e)^n

符号 ~ 表示“渐*等于”,即当n趋向于无穷大时,公式两边的比值趋*于1。

以下是关于斯特林公式的几个关键点:

  • 它提供了一个极其精确的、无需计算大量乘积即可估算巨大数值n!的方法。
  • 公式中的常数 √(2π) 是通过更深入的数学分析(如瓦利斯公式)得出的,本课程不展开证明。
  • 这个公式在概率论、组合数学和算法分析中会频繁出现,用于估算二项式系数等。

总结 📝

本节课中我们一起学*了如何估算乘积,特别是n的阶乘。

  1. 我们首先通过取对数,将 n! 的乘积问题转化为 ln(i) 的求和问题。
  2. 接着,我们应用积分方法,得到了 ln(n!) 的上下界。
  3. 通过启发式的*均处理和对数还原,我们推导出了 n! 的*似形式 √n * (n/e)^n
  4. 最后,我们介绍了更精确的最终版本——斯特林公式n! ~ √(2πn) * (n/e)^n。这个公式是计算机科学中估算阶乘大小的一个强大工具。

计算机科学的数学基础:L3.2.1:渐*符号

在本节课中,我们将学*描述函数增长率之间关系的四种渐*符号。这些符号是分析算法效率的核心工具,能帮助我们理解算法运行时间或空间需求随输入规模增长的变化趋势,而忽略掉具体的常数因子和低阶项。

渐*相等 (Asymptotically Equal)

上一节我们介绍了分析增长率的需求,本节中我们首先来看最简单的渐*关系:渐*相等

符号 f(n) ~ g(n) 读作“f(n) 渐*等于 g(n)”。其定义是:当 n 趋于无穷大时,f(n)g(n) 的比值的极限为 1。

公式

f(n) ~ g(n)  ⇔  lim (n→∞) [f(n) / g(n)] = 1

让我们看一个例子: 渐*等于 n² + n。原因如下:
计算极限 lim (n→∞) [(n² + n) / n²]。通过代数简化,该极限等于 lim (n→∞) [1 + 1/n]。当 n 趋于无穷大时,1/n 趋于 0,因此极限为 1。所以,这两个函数是渐*相等的。

从定义可以直接推导出渐*相等的一些简单性质。

以下是其主要性质:

  • 对称性:如果 f ~ g,那么 g ~ f。证明思路是考虑极限 lim (g/f),它等于 1 / lim (f/g),而后者为 1。
  • 传递性:如果 f ~ gg ~ h,那么 f ~ h。证明可通过极限的代数运算完成。

综上所述,渐*相等是一个等价关系。需要强调的是,这是函数之间的关系。当我们写 f(n) ~ g(n) 时,我们的意思是函数 f 渐*等于函数 g

渐*小于 (Asymptotically Smaller Than)

理解了渐*相等后,我们接下来看一个表示严格大小关系的符号:渐*小于

符号 f(n) = o(g(n)) 读作“f(n) 是 g(n) 的小 o”。其定义是:当 n 趋于无穷大时,f(n)g(n) 的比值的极限为 0。

公式

f(n) = o(g(n))  ⇔  lim (n→∞) [f(n) / g(n)] = 0

例如,n² = o(n³),因为 lim (n→∞) [n² / n³] = lim (n→∞) [1/n] = 0

类似于渐*相等,可以证明“小 o”关系构成了函数集上的一个严格偏序

渐*上界 (Big O Notation)

现在,我们来看计算机科学中 arguably 最重要、也最复杂的渐*关系:大 O 符号

符号 f(n) = O(g(n)) 读作“f(n) 是 g(n) 的大 O”。其定义是:f(n)g(n) 比值的上极限是一个有限数(即不为无穷大)。这粗略地意味着 f 的增长速度不超过 g 的某个常数倍。

公式

f(n) = O(g(n))  ⇔  lim sup (n→∞) [f(n) / g(n)] < ∞

(注:lim sup 表示上极限,目前我们可以先简单理解为“增长速率的上界是有限的”)。

例如,3n² = O(n²),因为比值 3n² / n² = 3,是一个有限常数。大 O 符号的关键在于它忽略了常数因子。这在计算机科学中非常有用,因为算法运行的具体时间依赖于硬件,但增长率是算法本身的属性。

渐*紧确界 (Theta Notation)

最后,我们介绍结合了“不超过”和“不低于”概念的符号:Θ 符号

符号 f(n) = Θ(g(n)) 读作“f(n) 是 g(n) 的 Θ”。其定义是:f(n) = O(g(n))g(n) = O(f(n))。这意味着 fg 的增长速率处于同一数量级。

公式

f(n) = Θ(g(n))  ⇔  f(n) = O(g(n)) 且 g(n) = O(f(n))

从定义可以直接得出,Θ 关系也是一个等价关系

总结

本节课中我们一起学*了四种描述函数增长率关系的渐*符号:

  • f ~ g (渐*相等):意味着 fg 的增长率几乎完全相同(比值的极限为1)。
  • f = o(g) (渐*小于):意味着 f 的增长率远小于 g(比值的极限为0)。
  • f = O(g) (大O):意味着 f 的增长率粗略地小于或等于 g(忽略常数因子)。
  • f = Θ(g) (Θ):意味着 fg 的增长率粗略地相等(处于同一数量级)。

这些符号是分析算法复杂度、比较算法效率的基础语言。在接下来的课程中,我们将更详细地探讨这些符号的性质和应用。

计算机科学的数学基础:L3.2.3:渐*符号的性质 📈

在本节课中,我们将学*渐*符号(大O、小o、渐*等价)的一些关键性质。我们将看到如何用极限来理解这些性质,并介绍标准的“limsup”定义。课程将涵盖几个基本事实,例如多项式与指数函数的增长比较,以及如何证明这些关系。

概述

本节将探讨渐*符号的数学性质。我们将从使用极限定义渐*符号的优点开始,然后过渡到更正式的标准定义。最后,我们会学*并证明几个关于函数增长率的、对计算机科学至关重要的基本事实。

用极限理解渐*符号

使用极限来定义渐*符号的一个优点是,许多性质会变得显而易见。

例如:

  • 如果 fg小o,或者 f 渐*等于 g,那么 f 也一定是 g大O
  • 非正式的解释是:fg小o 意味着 fg 小得多;f 渐*等于 g 意味着 fg 差不多大;而 fg大O 意味着 f 至多和 g 差不多大(或更小)。
  • 显然,“小得多”和“差不多”都蕴含了“至多差不多”。

我们可以使用极限定义来精确证明这一点:

  • f = o(g) 意味着 lim (f/g) = 0
  • f ~ g 意味着 lim (f/g) = 1
  • f = O(g) 意味着 limsup (f/g) 是有限的。
  • 由于 0 和 1 都是有限的数,因此前两种情况都满足 f = O(g)

另一个性质是,如果 f 远小于 g,那么 g 不会*似地小于或等于 f

更准确地说:如果 f = o(g),那么 g ≠ O(f)

  • 左边 f = o(g) 表示 lim (f/g) = 0
  • 这意味着 lim (g/f) = 1/0 = ∞(无穷大)。
  • 由于无穷大不是有限的,因此 g 不是 f大O

渐*符号的标准定义

上一节我们用极限直观地理解了性质,本节中我们来看看文献中更标准的定义。这个定义不直接使用极限,而是使用“limsup”(上极限)的概念。

让我展示一个标准定义,并解释为什么需要用到 limsup。

f = O(g) 的官方定义是:存在常数 c 和点 n₀,使得对于所有 n ≥ n₀,都有 f(n) ≤ c · g(n)

这个定义的核心思想是:你可以用一个常数 c 去放大 g,使得放大后的 c·g 从某个点 n₀ 开始,始终在 f 的上方。

让我们用图表来说明。假设绿色曲线是 f(n),蓝色曲线是 g(n)。最初,f 可能大于 g。但如果我们把 g 乘以一个常数 c,得到紫色曲线 c·g(n)。只要这个常数 c 足够大,紫色曲线从某个点 n₀ 开始就会一直位于绿色曲线上方。这就证明了 f = O(g)

(注:在标准坐标下,乘以常数是垂直拉伸。如果在纵轴使用对数刻度,乘以常数就相当于垂直*移,此时图示会更准确。)

使用这个标准定义,就能理解为什么在等价于极限的定义中,我们不能只说“极限”,而必须说“limsup”。

limsup 的作用如下:假设我有一个函数 f(n) ≤ 2g(n),根据定义,f 肯定是 O(g)。但 f(n)/g(n) 的极限可能不存在。

例如:令 f(n) = (1 + sin²(nπ)) · g(n)。因为 sin²(nπ) 在 0 和 1 之间交替,所以 f(n)/g(n) 就在 1 和 2 之间振荡,其极限不存在。然而,f(n)/g(n)limsup 是 2(有限的)。因此,根据 limsup 的定义,f = O(g) 仍然成立。

limsup 的技术定义是序列上极限点的最大值。在大多数实际情况下,极限是存在的,我们可以使用更简单的极限定义。但当极限不存在时,limsup 提供了严谨的表述方式。

关于增长顺序的基本事实

现在,让我们来学*几个关于小o和大O符号的基本事实,这些在算法分析中非常关键。

事实 1:多项式幂次的比较
如果 a < b(a, b 为实数),那么 xᵃ = o(xᵇ)
证明:根据定义,我们需要看极限 lim (xᵃ / xᵇ) = lim (1 / xᵇ⁻ᵃ)。因为 b - a > 0,当 x → ∞ 时,分母 xᵇ⁻ᵃ → ∞,所以整个极限为 0。这就证明了 xᵃ = o(xᵇ)

事实 2:对数函数与幂函数
对任意 ε > 0,有 log x = o(x^ε)。也就是说,对数比任何正的幂函数(如*方根、立方根)增长得都慢。
证明(思路):

  1. 从一个简单的不等式开始:对于 y ≥ 1,有 1/y ≤ y
  2. 对两边从 1 到 z 积分:
    • 左边:∫(1/y) dy = log z
    • 右边:∫ y dy = z²/2
    • 得到:log z ≤ z²/2 (当 z ≥ 1)。
  3. 做变量替换:令 z = x^(δ/2),其中 δ 是任意正数。
  4. 代入不等式,经过化简,可以得到 log x ≤ (2/δ) * x^δ
  5. 对于任意给定的 ε > 0,我们选择 δ 使得 δ < ε(例如 δ = ε/2)。那么 x^δ 的增长就比 x^ε 慢,再乘以常数后,依然有 log x = o(x^ε)

事实 3:多项式与指数函数
多项式函数比指数函数增长得慢。即,对于任意常数 ca > 1,有 x^c = o(a^x)
这个事实与“对数比根增长慢”密切相关。证明可以使用洛必达法则或麦克劳林级数,此处不做展开,你可以在微积分教材中找到它。

总结

本节课中,我们一起学*了渐*符号的核心性质。

  1. 我们首先用极限解释了渐*符号之间的关系(如 o 和 ~ 都蕴含 O)。
  2. 然后,我们探讨了 f = o(g)g ≠ O(f) 这一性质。
  3. 接着,我们介绍了 O(g) 更严谨的、基于常数和起点的标准定义,并理解了为什么需要引入 limsup 来处理极限不存在的情况。
  4. 最后,我们学*并证明了三个关于函数增长率的基本事实:
    • 低次多项式是高次多项式的小o。
    • 对数函数是任何正幂函数的小o。
    • 多项式函数是指数函数的小o。

掌握这些性质,对于后续分析算法的时间复杂度至关重要。

计算机科学的数学基础:P74:L3.2.6- 渐*符号常见错误 🚫

在本节课中,我们将学*在使用渐*符号,特别是大O符号时,人们常犯的一些错误。理解这些错误有助于我们更准确、更严谨地分析算法的复杂度。

概述

大O符号是描述函数增长率的强大工具,但它的表示法有时会让人产生误解。本节我们将剖析几个典型的误用案例,并解释其背后的正确概念。


大O符号的本质:一种关系,而非数量

首先,最重要的一点是理解大O符号的本质。像 1/x = O(1) 这样的表达式,其等号 = 实际上表示的是一种二元关系,而非两个数量之间的相等关系。

大O符号 O(f) 本身不是一个数量,因此不能将其当作一个数学对象进行常规的代数运算。历史上,曾有人建议用集合属于符号 来替代等号,这样更能体现“函数f属于由函数g定义的集合”这一本质。但由于大O表示法已在多个数学社区根深蒂固,这一改变未能实现。

对称性的陷阱

一个常见的错误源于对等号的误解,即认为关系具有对称性。例如,如果 f = O(g),就错误地写出 O(g) = f

以下是这种推理为何错误的分析:

  1. 我们知道 x = O(x) 显然成立。
  2. 如果错误地认为 O(x) = x 也成立(即对称性),那么 O(x) 就被当作了一个等于 x 的数量。
  3. 同时,根据大O定义,2x = O(x) 也成立。
  4. 2x = O(x)O(x) = x 结合起来,就会推导出 2x = x 的荒谬结论。

这清楚地表明,将 O(g) 视为一个数量并进行代数替换会导致矛盾。我们必须始终记住,f = O(g) 是一个整体,表示“f的增长率不超过g的常数倍”。


大O表示上界,而非下界

另一个虽不严重但不够严谨的错误,是误用大O来表达下界。

人们有时会说:“f 至少是 O(n²)”。这种说法的问题在于,“至少是 O(n²)” 试图将 O(n²) 当作一个可以比较大小的数量。

  • 正确的理解f = O(n²) 意味着 f 的一个渐*上界(在常数因子内)。
  • 如何表达下界:如果你想直观地说 f 的一个下界,正确的表述是 n² = O(f)。这表示 f 的增长率不低于 的增长率(即 f 至少和 增长得一样快)。

一个“错误证明”的案例分析

最后,我们来看一个更具迷惑性的错误示例,它错误地“证明”了前n个自然数之和是 O(n)。我们知道,实际上 1 + 2 + ... + n = n(n+1)/2,它是 Θ(n²)

以下是这个错误的证明过程:

  1. 首先注意到,任何常数都是 O(1)。例如,0, 1, 2 都是 O(1)。这是正确的。
  2. 在求和式 ∑_{i=1}^n i 中,每一项 i 都是一个具体的数(如1, 2, 3...)。根据上一点,每个 i 都可以写成 O(1)
  3. 因此,原求和式被写成:O(1) + O(1) + ... + O(1) (共n项)。
  4. 这等于 n * O(1)
  5. 由此得出结论:总和是 O(n)

这个证明错在哪里?
证明过程中隐含地使用了未经证实的“算术规则”。关键错误在于第二步:虽然每个单独的 i(视为常数函数)是 O(1),但这里的 i 并不是一个固定的常数,它随着循环索引变化。大O符号描述的是函数在输入趋于无穷时的整体行为,不能这样逐项替换并求和。O(1) 隐藏的常数因子可能各不相同,且可能依赖于 n,因此将它们简单相加的推理是无效的。这是初学者容易落入的思维陷阱。


总结

本节课我们一起学*了使用渐*符号时的三个常见错误:

  1. 切勿将大O视为数量:记住 f = O(g) 表示一种增长率上的比较关系,而非等式。不要对 O(g) 进行代数运算。
  2. 明确上下界:大O (O) 描述的是渐*上界。若想描述下界,应使用 Ω 符号,或通过 g = O(f) 来表达 fg 的下界。
  3. 避免滥用算术:不要随意对包含大O的表达式进行加、乘等算术运算,除非你严格遵循其数学定义。分析求和式或复杂表达式时,应回归定义进行整体判断。

理解并避免这些错误,能帮助我们在算法分析中更准确、更专业地使用渐*符号。

计算机科学的数学基础:L3.3.1:求和与乘积规则 📊

在本节课中,我们将要学*组合学中最基础的两个计数规则:求和规则与乘积规则。组合学是计算机科学等多个领域的重要数学基础,其起源与计算概率和可能性密切相关。掌握这些基本规则,是理解更复杂计数问题(如算法分析、密码学强度评估等)的第一步。

组合学的起源与应用 🎲

组合学与计数的起源与历史上的赌博研究有关,人们通过计算各种事件发生的次数来确定下注策略。一个典型的问题是计算在扑克游戏中,拿到特定手牌(如“一对J”)的概率。这需要计算所有可能的五张牌手牌总数中,属于该类别的手牌所占的比例。

在计算机科学中,组合学同样至关重要。例如,在编写棋类游戏程序时,需要估算为了向前预测,程序需要搜索多少种可能的棋局位置。解决魔方问题也涉及计算从给定状态可以到达多少种不同的位置。

在算法分析中,我们经常需要计算对数据结构进行操作所需的步骤数,例如对n个数字进行排序所需的比较次数,其典型的下界是 n log n。此外,在密码学领域,为了确保加密的安全性,密钥空间必须足够大,使得对手无法通过穷举搜索所有可能的密钥来破解。

基本计数规则:求和规则 ➕

上一节我们介绍了组合学的背景,本节中我们来看看第一个基本计数规则——求和规则。这条规则非常直观。

求和规则指出:如果两个集合A和B没有重叠(即互斥),那么它们的并集 A ∪ B 中的元素数量,等于集合A的元素数量加上集合B的元素数量。

用公式表示为:

|A ∪ B| = |A| + |B|, 其中 A ∩ B = ∅

以下是求和规则的两个简单例子:

  • 假设一个班级有43名女生和54名男生,且没有学生性别模糊。那么班级总人数就是女生与男生人数之和:43 + 54 = 97
  • 考虑由26个小写英文字母、26个大写英文字母和10个数字(0-9)组成的字符集。该字符集的总字符数为:26 + 26 + 10 = 62

基本计数规则:乘积规则 ✖️

了解了如何对互斥集合进行计数后,我们来看看另一种常见场景——对有序组合进行计数的乘积规则。

乘积规则指出:如果一个任务可以通过两个连续的步骤完成,第一步有 m 种方法,第二步有 n 种方法,那么完成整个任务总共有 m × n 种方法。从集合角度看,如果集合A的大小为 m,集合B的大小为 n,则从A和B中各取一个元素构成有序对 (a, b) 的所有可能组合数为 m × n

用公式表示为:

|A × B| = |A| × |B|

以下是乘积规则的一个例子:

  • 假设有4个男孩和3个女孩,要组成一对男女搭档。选择男孩有4种方法,对于每个被选中的男孩,选择女孩都有3种方法。因此,总共可以组成 4 × 3 = 12 对不同的搭档。

更一般地,我们可以用乘积规则来计算字符串的数量。例如,考虑长度为4的二进制字符串(由0和1组成)。我们可以将构造这样一个字符串的过程,视为依次为4个位置中的每一个选择数字(0或1)。每个位置都有2种选择。根据乘积规则,总的字符串数量为:

2 × 2 × 2 × 2 = 2^4 = 16

推广到一般情况:如果一个字符串的长度为 n,且每个字符都来自一个大小为 m 的字母表,那么可能的字符串总数为:

m^n

总结 📝

本节课中我们一起学*了组合学中最基础的两个计数工具。

  • 求和规则用于计算多个互斥事件或集合的总可能性数量,其核心是加法
  • 乘积规则用于计算多个连续选择步骤产生的总可能性数量,其核心是乘法

这两个规则虽然简单,但它们是解决更复杂计数问题的基石,在算法分析、概率计算以及密码学等领域都有广泛应用。理解并熟练运用它们是深入学*计算机科学数学基础的关键一步。

计算机科学的数学基础:L3.3.3:用双射计数 📊

在本节课中,我们将学*组合学中的一个核心技巧——双射计数。我们将通过几个具体的例子,展示如何通过建立两个集合之间的双射关系,将一个难以直接计算的问题转化为一个更容易计算的问题。


概述

双射计数的基本思想是:通过计算一个已知或更易计算的集合的大小,来推断另一个与之存在一一对应关系的集合的大小。这是一种非常强大的工具,可以简化许多计数问题。


从简单计数开始

上一节我们介绍了基本的和规则与积规则。本节中,我们来看看如何应用这些规则解决一个简单的密码计数问题。

假设我们要计算符合特定规则的密码数量。密码定义如下:

  • 密码是字母或数字组成的字符序列。
  • 长度在6到8个字符之间。
  • 必须以一个字母开头。
  • 区分大小写(即大小写字母视为不同字符)。

我们定义:

  • 字母集合 L(包含大小写字母,共52个)。
  • 数字集合 D(0-9,共10个)。

首先,我们考虑长度为 n 的密码集合 P_n。根据规则,密码的第一个字符必须是字母,其余 n-1 个字符可以是字母或数字。

因此,一个长度为 n 的密码可以表示为:
P_n = L × (L ∪ D)^{n-1}

根据乘积规则,P_n 的大小为:
|P_n| = |L| × |L ∪ D|^{n-1}

由于字母和数字集合不相交,根据和规则,|L ∪ D| = |L| + |D|

代入数值(|L|=52, |D|=10),我们得到公式:
|P_n| = 52 × 62^{n-1}

接下来,所有有效密码的集合 P 是长度为6、7、8的密码集合的不相交并集
P = P_6 ∪ P_7 ∪ P_8

根据和规则,总密码数为:
|P| = |P_6| + |P_7| + |P_8| = 52 × (62^5 + 62^6 + 62^7)

计算可得总数约为 1.9 × 10^{14}。这是一个直接应用和与积规则的典型例子。


计数技巧:补集与直接分解

现在,我们考虑另一个问题:有多少个四位数字(序列)至少包含一个数字7?

方法一:直接分解(按第一个7出现的位置)

我们可以根据“第一个7”出现在序列中的位置(第1、2、3或4位)来分类计数。令:

  • 7 代表数字7。
  • X 代表任意数字(0-9,共10种可能)。
  • O 代表除7以外的任意数字(0-6, 8-9,共9种可能)。

以下是所有可能模式及其计数:

  1. 模式 7XXX:第一个是7,后三位任意。计数为 1 × 10 × 10 × 10 = 10^3
  2. 模式 O7XX:第一个不是7,第二个是7,后两位任意。计数为 9 × 1 × 10 × 10 = 9 × 10^2
  3. 模式 OO7X:前两个不是7,第三个是7,最后一位任意。计数为 9 × 9 × 1 × 10 = 9^2 × 10
  4. 模式 OOO7:前三个不是7,第四个是7。计数为 9 × 9 × 9 × 1 = 9^3

由于这些模式通过“第一个7的位置”区分,它们互不相交。根据和规则,总数为:
10^3 + (9 × 10^2) + (9^2 × 10) + 9^3 = 3439

方法二:使用补集计数

一个更巧妙的方法是先计算其补集。所有四位数字序列的总数是 10^4。其中“不包含任何数字7”的序列,每一位只能从9个数字(0-6, 8-9)中选择,共有 9^4 个。

因此,至少包含一个7的序列数为:
10^4 - 9^4 = 10000 - 6561 = 3439

两种方法得到了相同的结果。补集法通常更简洁。


引入双射规则 🧩

以上我们使用了基本的和与积规则。现在,我们引入并应用双射规则

双射规则指出:如果存在两个有限集合 A 和 B 之间的一个双射(一一对应),那么这两个集合的大小相等。即,若 f: A ↔ B 是双射,则 |A| = |B|


示例1:子集的数量

问题:一个包含 n 个元素的集合,总共有多少个子集?

设集合 A = {a1, a2, ..., an}。我们希望计算 A 的所有子集构成的集合(称为幂集)的大小。

我们可以在 A 的子集长度为 n 的二进制字符串 之间建立一个双射。

  • 对于一个给定的子集 S,我们构造一个二进制字符串 b1b2...bn,其中:
    • 如果 ai ∈ S,则 bi = 1
    • 如果 ai ∉ S,则 bi = 0
  • 反之,给定任何一个长度为 n 的二进制字符串,我们可以唯一地确定它对应的子集。

这建立了一个一一对应关系(双射)。我们知道,长度为 n 的二进制字符串共有 2^n 个(每位有2种选择,根据乘积规则)。

因此,根据双射规则,集合 A 的子集总数也是:
|P(A)| = 2^n

这个结论可以优雅地表述为:一个集合的幂集的大小是 2 的该集合大小次方


示例2:甜甜圈选择问题 🍩

这是一个更有趣的例子,它展示了即使我们暂时不知道如何计算双方,双射也能告诉我们两个集合大小相等。

问题:有5种不同口味的甜甜圈(巧克力、柠檬、糖霜、原味釉面等)。要选择一打(12个)甜甜圈,共有多少种不同的选择方式?(同一种口味的甜甜圈被视为无区别的)。

设集合 A 为所有可能的“12个甜甜圈选择”的集合。

我们可以在集合 A 和另一个集合 B 之间建立双射。集合 B 定义如下:

  • B 是所有包含 恰好4个‘1’16位二进制字符串 的集合。

双射的建立方法如下:

  1. 想象我们将12个甜甜圈(用‘0’表示)排成一排。
  2. 我们需要用4个‘1’作为“分隔符”,将这12个‘0’分成5个组(对应5种口味)。
  3. 第一个‘1’之前的‘0’的数量代表第一种口味(如巧克力)的甜甜圈数。
  4. 第一个和第二个‘1’之间的‘0’的数量代表第二种口味(如柠檬)的甜甜圈数。
  5. 依此类推,直到最后一个‘1’之后的‘0’的数量代表第五种口味的甜甜圈数。

例如: 选择 2巧克力, 0柠檬, 6糖霜, 2釉面, 2原味

  • 对应的二进制字符串为:00 1 1 000000 1 00 1 00
  • 简化表示为:0011000000100100(共12个0,4个1)。

反之,给定任何一个恰好包含4个‘1’的16位字符串,我们可以唯一地还原出每种口味甜甜圈的数量,从而确定一个甜甜圈选择方案。

因此,我们成功地在 甜甜圈选择方案集合 A恰好包含4个‘1’的16位字符串集合 B 之间建立了一个双射。

根据双射规则,我们得出结论:
|A| = |B|

尽管我们现在还不知道如何计算 |B|(我们将在后续课程中学到),但我们已经通过双射将原问题转化为了一个标准且易于后续处理的问题。


总结

本节课中我们一起学*了:

  1. 双射计数的核心思想:通过建立两个集合间的一一对应,将未知的计数问题转化为已知或更易计算的问题。
  2. 回顾并应用了和规则积规则来解决基础的计数问题(如密码计数)。
  3. 学*了补集计数这一实用技巧。
  4. 通过两个经典例子(子集计数甜甜圈选择)深入理解了如何构造双射,并利用双射规则得出计数结论。

双射是组合数学中一个非常基本且强大的工具,它能够揭示不同数学对象之间深刻的数量联系。掌握这一技巧,将为解决更复杂的计数问题打下坚实的基础。

计算机科学的数学基础:L3.4.1:广义计数规则 📊

在本节课中,我们将学*计数规则的两个重要推广:广义乘积规则和广义双射规则(除法规则)。这些规则是组合数学中的核心工具,对于计算各种情况下的可能性数量至关重要。

广义乘积规则 ✖️

上一节我们介绍了基本的计数规则,本节中我们来看看其推广形式。广义乘积规则用于计算无重复的序列数量。

假设我们要计算从91名学生中选出5名学生进行排队(即一个序列)的方法数。如果同一个学生可以出现多次,那么根据普通乘积规则,方法数为 91^5。然而,在实际排队中,一个学生不能出现两次,即序列中不能有重复元素。

广义乘积规则可以解决这个问题。计算过程如下:

  • 选择第一名学生有91种方法。
  • 选择第二名学生时,只剩下90名可选。
  • 选择第三名学生时,剩下89名可选。
  • 以此类推,选择第五名学生时,剩下87名可选。

因此,长度为5的不同学生序列总数为:
91 × 90 × 89 × 88 × 87

这个结果可以用阶乘简洁地表示为 91! / 86!

现在,让我们一般性地陈述广义乘积规则。

Q 是一组长度为 k 的序列,并满足以下属性:

  • n1 种可能的选择作为序列的第一个元素。
  • 对于每一个确定的第一个元素,都有 n2 种可能的选择作为序列的第二个元素。
  • 同样,对于每一对确定的前两个元素,都有 n3 种可能的选择作为第三个元素。
  • 此规律持续到第 k 个元素。

那么,满足这些属性的不同序列的总数为:
n1 × n2 × n3 × ... × nk

广义双射规则(除法规则) ➗

接下来,我们探讨双射规则的推广,它被称为除法规则。一个简单易懂的类比是:如果你想数清一个班级的学生人数,你可以先数所有学生的手指总数,然后除以10(假设每个学生都有10根手指)。当然,这假设了每个学生的手指数量是恒定且已知的。

更形式化地说,除法规则如下:

如果存在一个从集合 A 到集合 B满射函数 f,并且这个函数是 k 对 1 的映射(即 B 中的每一个元素都恰好被 A 中的 k 个元素映射到),那么两个集合的大小关系为:
|A| = k × |B|
由此可得:
|B| = |A| / k

关键应用:二项式系数 🔑

除法规则的一个关键且基础的应用是计算组合数,即从一个集合中选出指定大小子集的方法数。我们会反复使用这个结果。

问题:从数字 {1, 2, ..., 13} 中,有多少种方法可以选出一个大小为4的子集?

解决方法

  1. 设集合 A 为数字1到13的所有排列(即顺序序列)。我们知道 |A| = 13!
  2. 设集合 B 为我们想要计数的对象,即所有大小为4的子集。|B| 是未知的。
  3. 我们构造一个从 AB 的函数 f:对于一个排列,取其前四个元素,并忽略顺序,将它们视为一个集合。例如,排列 (3, 1, 4, 2, 5, 6, ..., 13) 被映射到集合 {1, 2, 3, 4}
  4. 现在,我们需要确定这个映射是“几对1”的。考虑一个特定的4元素子集,例如 {1, 2, 3, 4}。哪些排列会被映射到这个集合?
    • 前四个位置必须是1,2,3,4的某种排列,共有 4! 种方式。
    • 后九个位置可以是剩余数字 {5, ..., 13} 的任意排列,共有 9! 种方式。
    • 因此,总共有 4! × 9! 个不同的排列会被映射到同一个子集 {1, 2, 3, 4}。这意味着函数 f(4! × 9!) 对 1 的映射。
  5. 根据除法规则:
    |A| = (4! × 9!) × |B|
    13! = (4! × 9!) × |B|
    所以:
    |B| = 13! / (4! × 9!)

这个结果极其重要,它定义了二项式系数,记作:
C(13, 4)(13 choose 4),其计算公式为 13! / (4! × 9!)

将其推广:从一个 n 元素集合中选出 m 个元素的子集的方法数,即组合数,由以下二项式系数公式给出:
C(n, m) = n! / (m! × (n-m)!)
这个公式需要牢记。


本节课总结
本节课我们一起学*了两个核心的广义计数规则。

  1. 广义乘积规则:用于计算具有特定约束(如无重复)的序列总数,公式为各阶段选择数的乘积。
  2. 除法规则:是双射规则的推广,通过建立一个 k 对 1 的满射,利用已知集合大小来求解未知集合大小。
    我们还将除法规则应用于一个经典问题,推导出了计算组合数的二项式系数公式 C(n, m) = n! / (m! × (n-m)!),这是组合数学中最基本和最重要的公式之一。

计算机科学的数学基础:L3.4.3:双对扑克手牌计数 🃏

在本节课中,我们将学*一个计数问题的基本示例,它展示了广义除法规则和广义乘积规则的应用。我们将具体计算一种被称为“双对”的扑克手牌数量。

扑克是一种游戏,每位玩家会从一副52张的牌中获得5张牌。双对手牌的定义是:手牌中包含两对相同点数的牌(即两个“对子”),以及一张与这两对点数都不同的第五张牌。

理解双对手牌

首先,我们来明确一下扑克牌的基本构成。一副牌有52张,分为13个点数(A, 2, 3, ..., 10, J, Q, K)和4个花色(♦ 方块, ♥ 红心, ♠ 黑桃, ♣ 梅花)。

一个双对手牌的结构如下:

  1. 一个由两张相同点数牌组成的“对子”。
  2. 另一个由两张相同点数牌组成的“对子”,但其点数必须与第一个对子不同。
  3. 一张点数与上述两个对子都不同的第五张牌。

例如,一手双对牌可能是:两张K(K♦ 和 K♥),两张A(A♦ 和 A♠),以及一张3(3♣)。

初步计数尝试

上一节我们定义了双对手牌。本节中,我们来看看如何系统地计算其总数。一个直观的思路是,通过一系列选择来构建一手牌。

以下是构建一手双对牌的步骤:

  1. 选择第一个对子的点数:有13种可能(A到K)。
  2. 选择第二个对子的点数:必须与第一个不同,因此有12种可能。
  3. 选择第五张牌的点数:必须与前两个都不同,因此有11种可能。
  4. 为第一个对子选择花色:从4种花色中选2种,组合数为 C(4, 2)
  5. 为第二个对子选择花色:同样,组合数为 C(4, 2)
  6. 为第五张牌选择花色:有4种可能。

根据广义乘积规则,将每一步的选择数相乘,似乎就能得到总数。其计算公式为:
13 * 12 * 11 * C(4, 2) * C(4, 2) * 4

发现并修正错误

然而,这个计算存在一个错误。问题在于,我们的步骤序列(第一个对子、第二个对子)人为地为两个对子指定了“第一”和“第二”的顺序。

但实际上,一手双对牌中的两个对子是没有顺序之分的。“一对K和一对A”与“一对A和一对K”描述的是同一手牌。在我们的计数过程中,我们却将它们计为了两种不同的构建序列。

具体来说,我们构建的六元组 (第一个点数, 第二个点数, 第五张牌点数, 第一个花色组合, 第二个花色组合, 第五张牌花色) 与双对手牌之间的映射关系是 2对1 的。对于同一手牌(如K对和A对),我们有两种构建它的六元组:一种把K对当作“第一个对子”,另一种把A对当作“第一个对子”。

应用除法规则修正

既然我们已经正确地计算了所有可能的六元组数量,并且知道每个双对手牌都恰好对应 2个 这样的六元组,那么根据除法规则,双对手牌的实际数量就是六元组总数除以2。

因此,正确的计算公式为:
(13 * 12 * 11 * C(4, 2) * C(4, 2) * 4) / 2

让我们计算一下:

  • C(4, 2) = 6
  • 分子部分:13 * 12 * 11 * 6 * 6 * 4 = 247,104
  • 最终结果:247,104 / 2 = 123,552

所以,一副标准扑克牌中,总共有 123,552 种不同的双对手牌。

总结

本节课中我们一起学*了如何计算扑克牌中“双对”手牌的数量。我们首先尝试用广义乘积规则直接计算,但发现由于忽略了两个“对子”之间的无序性,导致了重复计数。然后,我们通过识别映射关系是2对1的,并应用除法规则,成功地修正了公式,得到了正确的计数结果 123,552。这个例子清晰地展示了在计数问题中,仔细分析被计数对象之间映射关系的重要性。

计算机科学的数学基础:P79:L3.4.4- 二项式定理 📚

在本节课中,我们将要学*二项式定理。这是一个在高中代数中可能已经接触过的概念,但它也是代数与组合计算之间联系的绝佳例证。我们将从分配律这一基础思想出发,逐步推导出二项式定理的公式,并理解其背后的组合意义。

从分配律到乘积之和

上一节我们介绍了分配律的基本思想,本节中我们来看看它如何扩展到多个项。分配律的核心思想是:和的乘积可以转化为乘积的和。

为了直观说明,考虑一个简单的例子:(a + b) * (c + d)。应用分配律,我们得到:

(a + b) * (c + d) = a*c + a*d + b*c + b*d

我们看到,最终的和包含了从第一个括号和第二个括号中各选一项进行相乘的所有可能组合。

当我们将这个规则扩展到 n(1 + x) 相乘时,情况是类似的。表达式 (1 + x)^n 的展开,本质上就是反复应用分配律的结果。

二项式定理的推导

现在,让我们具体看看 (1 + x)^n 的展开式。我们知道这将是一个 n 次多项式,可以写成以下形式:

(1 + x)^n = C0 + C1*x + C2*x^2 + ... + Ck*x^k + ... + Cn*x^n

我们的目标是找出系数 Ck 的表达式。

(1 + x)^4 为例,其展开式为:

(1 + x)^4 = 1 + 4x + 6x^2 + 4x^3 + x^4

系数模式为 1, 4, 6, 4, 1。这个模式是如何产生的?

关键在于理解 (1 + x)^nn(1 + x) 因子的乘积。展开时,我们需要从每一个因子 (1 + x) 中选择 1 或者 x 进行相乘,然后将所有可能的乘积相加。

  • 如果从所有 n 个因子中都选择 1,则得到项 1^n = 1
  • 如果从所有 n 个因子中都选择 x,则得到项 x^n
  • 更一般地,如果从 n 个因子中恰好选择 kx(那么剩下的 n-k 个因子自然选择 1),则得到项 x^k * 1^(n-k) = x^k

那么,在最终的展开式中,x^k 项会出现多少次呢?这等价于问:n 个因子中,选出 k 个因子令其贡献 x(其余贡献 1),有多少种不同的选法?

根据组合数学的定义,这个数量正是 二项式系数,记作:

Ck = C(n, k) = n choose k

因此,我们得到了二项式定理的标准形式:

(1 + x)^n = Σ_{k=0}^{n} C(n, k) * x^k

其中 Σ 表示求和,k0n

更一般的形式

我们之前使用了 (1 + x) 是为了简化推导,让结构更清晰。二项式定理可以推广到更一般的形式 (x + y)^n

(x + y)^n 的展开中,我们需要从每个因子 (x + y) 中选择 xy。如果一项包含了 kx,则必然包含 n-ky,该项为 x^k * y^(n-k)。而得到这样一项的方法数,同样是从 n 个因子中选择 k 个来取 x(剩下的取 y),即 C(n, k) 种。

因此,二项式定理的一般形式为:

(x + y)^n = Σ_{k=0}^{n} C(n, k) * x^k * y^(n-k)

这个公式完美地展示了代数展开与组合选择之间的深刻联系:展开式中每一项的系数,正对应着取得该项所有可能方式的数量。

总结

本节课中我们一起学*了二项式定理。我们从基础的分配律出发,理解了多个二项式因子相乘时,展开式是所有可能选择方式的乘积之和。进而,我们推导出 (1 + x)^n 和更一般的 (x + y)^n 的展开公式,并认识到其中的系数 C(n, k)(即二项式系数)具有明确的组合意义:它代表了在 n 次独立选择中,恰好进行 k 次特定选择的方案总数。这一定理是连接多项式代数与组合计数的一个重要桥梁。

计算机科学的数学基础:P80:L3.4.5- 多项式定理 📚

在本节课中,我们将要学*二项式定理的扩展——多项式定理。我们将从一个有趣的“簿记员规则”开始,理解如何计算包含重复元素的排列数,并最终推导出多项式定理的一般形式。


从二项式到多项式

上一节我们介绍了二项式定理,它处理的是两个项之和的幂次展开。本节中我们来看看它的扩展形式,即多项式定理。多项式定理处理的是多个项之和的幂次展开

二项式定理扩展为一种称为多项式定理的形式。其核心区别在于,我们不再处理两个项之和的乘积,而是处理K个项之和的乘积


簿记员规则 📖

理解多项式定理的基础是一个我们称之为“簿记员规则”的计数规则。这个名称源于一个具体的例子。

以下是簿记员规则要解决的问题:观察单词“bookkeeper”,并问有多少种不同的方式可以打乱这个单词中的字母,使其成为可区分的排列?关键在于,两个字母“O”是不可区分的,它们出现的顺序无关紧要。同样,三个字母“E”和两个字母“K”也是如此。

我们如何回答这个问题?一个简单的方法是,首先给所有不可区分的字母加上下标,使它们变得可区分。

  • 我给两个“O”加上下标1和2。
  • 给两个“K”加上下标1和2。
  • 给三个“E”加上下标1、2和3。

现在,这十个字母都是可区分的了。如果我问有多少种方式排列这十个字母,根据广义乘积规则,答案显然是 10!

我的策略是使用除法规则来计算没有下标的字母排列模式的数量。具体做法是:取一个带下标的单词排列,然后擦掉下标。我将它映射到同一个没有下标的字母排列。

例如,我取一个带下标单词的任意排列,然后擦掉下标并合并字母,最终得到这个排列。现在,如果我想计算没有下标的排列数量,我只需要计算出这个映射是“多对一”的。

具体来说,有多少个带下标的单词会映射到给定的无下标模式?答案是:

  • “O”的下标顺序无关紧要,所以下标有 2! 种可能的排列顺序。
  • “K”的下标顺序无关紧要,所以下标有 2! 种可能的排列顺序。
  • “E”的下标顺序无关紧要,所以下标有 3! 种可能的排列顺序。

因此,对于两个“O”、两个“K”和三个“E”,这个映射是 2! × 2! × 3! 对 1。根据除法规则,单词“bookkeeper”的字母排列总数是:

10! / (2! × 2! × 3!)

更一般地,通过同样的推理,如果我观察一个由n个字母组成的序列,其中有n₁个A,n₂个B,……,nₖ个Z,那么这些包含重复A、B、Z的字母的排列数是:

n! / (n₁! × n₂! × … × nₖ!)

这个公式出现得非常频繁,因此它有一个名字,叫做多项式系数。其记法为:

n choose (n₁, n₂, …, nₖ)

约定是,所有nᵢ的和等于分子n。二项式系数是多项式系数的一个特例。如果我们把它写成多项式系数,就是 n choose (k, n-k)


应用:展开多项式

我们可以应用这个规则来思考多于二项式的展开式中的系数。

让我们看一个展开五元式的例子:一个包含五个项(E, M, S, T, Y)的和的七次方。

(E + M + S + T + Y)⁷

这意味着,在这七个项的乘积中,我得到的是长度为七的“单词”,其组成部分是字母E, M, S, T, Y。如果我应用分配律将其乘开,最终会得到 5⁷ 个项,每个项都是由字母E, M, S, T, Y组成的一个排列。

如果我问,在这个展开式中,项 E M S³ T Y 的系数是多少?它恰好就是排列这五个字母的方式数量——一个由这五个字母组成、长度为七、其中S出现三次的单词。换句话说,在这个乘积中,E M S³ T Y 的系数就是重新排列这个由七个字母组成的序列的方式数量。我们选择的这个序列是单词“systems”。

根据簿记员规则,重新排列单词“systems”中字母的方式数量是:

7 choose (1, 1, 3, 1, 1)

让我们做另一个例子。如果我展开这个三项式 (B + A + N)⁶,项 B A³ N² 的系数是多少?

现在,我有 3⁶ 个项。其中有多少项包含一个B、三个A和两个N?根据簿记员规则,它就是重新排列单词“banana”中字母的方式数量。根据簿记员规则,那就是:

6 choose (1, 3, 2)


多项式定理的一般形式

更一般地,这就是多项式定理所说的内容:如果我在一个K项之和(K个不同变量的和)的n次幂展开式中,寻找项 ∏ Xᵢ^(rᵢ) 的系数(即X₁出现r₁次,X₂出现r₂次,……,Xₖ出现rₖ次)。

如果我使用分配律展开而不合并同类项,我会得到 Kⁿ 个项,每个项都是X₁到Xₖ的一个排列(允许重复)。然后,如果我问,在这些K个变量的乘积中,有多少个具有这么多X₁、这么多X₂……这么多Xₖ?我再次问了一个簿记员问题,答案是:

n choose (r₁, r₂, …, rₖ)

现在,我们准备好记录下一般的多项式公式了。如果我取一个K项之和(一个K项式)的n次幂,那么用简洁的符号表示,其展开式为:

∑_{(r₁+…+rₖ=n)} [ n choose (r₁, …, rₖ) × (X₁^(r₁) … Xₖ^(rₖ)) ]

这个公式本身不需要特别记忆,它充满了下标,显得有些复杂。但尽管如此,有时记录下来是有益的。


总结

本节课中我们一起学*了:

  1. 簿记员规则:用于计算包含重复元素的排列数,公式为 n! / (n₁! × n₂! × … × nₖ!)
  2. 多项式系数:记作 n choose (n₁, n₂, …, nₖ),是上述公式的简记法,二项式系数是其特例。
  3. 多项式定理:将二项式定理推广到多个项之和的幂次展开,展开式中特定项的系数由对应的多项式系数给出。

下周我们将继续探讨计数与代数之间的联系,不仅限于我们在这里看到的普通多项式(和的乘积),事实上还包括无限多项式或无穷级数。

计算机科学的数学基础:L3.5.1:鸽子洞原理 🐦

在本节课中,我们将学*一个在计算机科学和数学中都非常基础且强大的计数原理——鸽子洞原理。这个原理看似简单,却能帮助我们解决许多有趣的问题。

概述

鸽子洞原理是一种基本的计数原理。它以一种非常直观的方式描述了当物品数量超过容器数量时必然出现的现象。我们将学*它的基本形式、正式表述以及如何应用它来解决一些简单问题。

鸽子洞原理的基本形式

上一节我们介绍了计数的基本概念,本节中我们来看看鸽子洞原理。

鸽子洞原理的基本形式非常明显:如果鸽子数量多于鸽子洞的数量,那么至少有一个鸽子洞里会有两只或更多的鸽子。

这实际上是对一个我们已经知道的映射规则的非正式说法。从集合论的角度,我们可以这样正式描述:

  • 如果存在一个从集合 A 到集合 B完全单射,那么意味着集合 A 的大小小于或等于集合 B 的大小。
  • 反之,如果集合 A 的大小大于集合 B 的大小,那么从 AB 的完全单射就是不可能的。

“没有完全单射”意味着在映射关系中,B 中的至少一个元素会对应 A 中的两个或更多元素。这就像至少有两“只”鸽子飞进了同一个“洞”。

原理的应用

我们已经知道了这个规则,唯一令人惊讶的是如何利用它。我们不打算在本视频中进行复杂的应用,但你可以在课程资料中读到一些有趣的例子,例如证明波士顿地区一定有三个人拥有完全相同数量的头发,或者证明在九十个由两个五位数组成的数字中,一定存在和相同的两个数。

下面,我们将更温和地应用鸽子洞原理。

示例:扑克牌的花色

假设我手上有五张牌。那么我至少拥有两张同一花色的牌。为什么?因为只有四种花色(红心、黑桃、梅花、方块)。

如果你有五张牌(鸽子),但只有四个花色(洞),那么当你把牌分配到花色中时,鸽子(牌)必须聚集在一起。因此,至少有一个花色里会有两只或更多的鸽子,也就是说至少有两张同一花色的牌。

原理的推广

让我们进一步推广。假设我有十张牌。我保证至少拥有多少张同一花色的牌?

现在有四个“插槽”(花色),我需要分发十张卡片。有没有可能每个花色里都少于三张牌?不可能。

因为如果每个花色最多只有两张牌,那么我最多只能分配 4 * 2 = 8 张牌。但我有十张牌需要分配到四个花色中,所以我必须把一些牌“捆”在一起,导致至少有一个花色拥有三张或更多的牌。

你可以验证,这里的推理是:同一花色的最少牌数,是将你的牌数除以花色数,并意识到至少有一个花色必须拥有不低于*均数的牌数。

更一般地,如果我们有 n 只鸽子(物品)要分配到 h 个独特的洞(类别)中,那么某个洞里鸽子的数量至少n / h 向上取整的值。

n / h 可以理解为每个洞里鸽子的*均数量。因此,鸽子洞原理可以表述为:至少有一个洞必须容纳大于或等于*均数的鸽子

用公式表示这个推广形式:

设鸽子数为 n,洞数为 h,则至少有一个洞包含不少于 ⌈n / h⌉ 只鸽子。

总结

本节课中,我们一起学*了鸽子洞原理。我们从其直观的基本形式(鸽子多于洞则必有共享)开始,然后看到了它在集合论中的正式对应关系(完全单射的不可能性)。最后,我们通过扑克牌的例子学*了如何应用这个原理,并将其推广为一个可以计算“至少有多少”的通用公式 ⌈n / h⌉。这个简单而强大的原理是解决许多计数和存在性问题的基石。

计算机科学的数学基础:L3.5.3:容斥原理示例 📊

在本节课中,我们将学*一个重要的计数规则——容斥原理。我们将从一个简单的两集合情况开始,然后将其推广到三个集合,并通过一个具体的数字排列示例来应用这个原理。

概述

容斥原理是加法法则的推广,用于计算多个集合的并集大小,尤其适用于这些集合之间存在重叠的情况。我们将首先理解其基本形式,然后通过一个包含特定数字模式的排列计数问题来实践应用。

两集合的容斥原理

上一节我们介绍了加法法则,它适用于互不相交的集合。本节中我们来看看当集合存在重叠时,如何计算并集的大小。

加法法则指出,如果两个集合 AB 互不相交(即 A ∩ B = ∅),那么它们的并集大小为:
|A ∪ B| = |A| + |B|

然而,如果 AB 存在重叠,直接相加会将重叠部分计算两次。因此,我们需要减去一次重叠部分。容斥原理的公式为:
|A ∪ B| = |A| + |B| - |A ∩ B|

直观解释是:当我们计算 |A| + |B| 时,属于交集 A ∩ B 的元素被计算了两次。为了得到正确的总数,我们必须减去一次交集的大小,确保每个元素只被计数一次。

三集合的容斥原理

理解了两个集合的情况后,我们现在将其推广到三个集合。计算 A ∪ B ∪ C 的大小需要更复杂的公式。

对于三个集合 ABC,容斥原理的公式为:
|A ∪ B ∪ C| = |A| + |B| + |C| - |A ∩ B| - |A ∩ C| - |B ∩ C| + |A ∩ B ∩ C|

这个公式的逻辑是:先加上所有单个集合的大小,这会使得两两重叠的区域被计算两次,三重重叠的区域被计算三次。然后,减去所有两两交集的大小,这会使得三重重叠的区域被减去三次,从而未被计数。最后,再加上三重重叠区域的大小,以确保每个元素都被精确计数一次。可以总结为:奇数个集合的交集项为正号,偶数个集合的交集项为负号。

应用示例:数字排列计数

现在,让我们应用三集合的容斥原理来解决一个具体的计数问题。我们将计算数字0到9的所有排列中,包含特定连续数字模式的排列数量。

我们考虑以下三个模式:

  1. 连续出现“6 0”。
  2. 连续出现“0 4”。
  3. 连续出现“4 2”。

定义集合:

  • P₆₀:包含“6 0”模式的排列集合。
  • P₀₄:包含“0 4”模式的排列集合。
  • P₄₂:包含“4 2”模式的排列集合。

我们的目标是计算 |P₆₀ ∪ P₀₄ ∪ P₄₂|,即至少包含其中一个模式的排列总数。

根据容斥原理:
|P₆₀ ∪ P₀₄ ∪ P₄₂| = |P₆₀| + |P₀₄| + |P₄₂| - |P₆₀ ∩ P₀₄| - |P₆₀ ∩ P₄₂| - |P₀₄ ∩ P₄₂| + |P₆₀ ∩ P₀₄ ∩ P₄₂|

接下来,我们分别计算公式中的每一项。

以下是各项的计算过程:

  1. 计算单个集合的大小(如 |P₆₀|)
    将“6 0”视为一个整体对象。那么我们需要排列的对象包括:这个“6 0”对象,以及剩下的8个独立数字(1, 2, 3, 4, 5, 7, 8, 9)。总共有9个对象,排列方式为 9!
    因此,|P₆₀| = |P₀₄| = |P₄₂| = 9!

  2. 计算两两交集的大小

    • |P₆₀ ∩ P₄₂|:排列包含“6 0”和“4 2”。将这两个模式视为两个独立对象。需要排列的对象包括:“6 0”对象、“4 2”对象,以及剩下的6个独立数字(1, 3, 5, 7, 8, 9)。总共有8个对象,排列方式为 8!
    • |P₆₀ ∩ P₀₄|:排列同时包含“6 0”和“0 4”,这等价于包含连续模式“6 0 4”。将这个“6 0 4”视为一个对象。需要排列的对象包括:这个“6 0 4”对象,以及剩下的7个独立数字(1, 2, 3, 5, 7, 8, 9)。总共有8个对象,排列方式为 8!
    • |P₀₄ ∩ P₄₂|:排列同时包含“0 4”和“4 2”,这等价于包含连续模式“0 4 2”。将这个“0 4 2”视为一个对象。需要排列的对象包括:这个“0 4 2”对象,以及剩下的7个独立数字(1, 3, 5, 6, 7, 8, 9)。总共有8个对象,排列方式为 8!
      因此,所有两两交集的大小均为 8!
  3. 计算三重重集的大小
    |P₆₀ ∩ P₀₄ ∩ P₄₂|:排列同时包含“6 0”、“0 4”和“4 2”,这等价于包含连续模式“6 0 4 2”。将这个“6 0 4 2”视为一个对象。需要排列的对象包括:这个“6 0 4 2”对象,以及剩下的6个独立数字(1, 3, 5, 7, 8, 9)。总共有7个对象,排列方式为 7!

代入公式并计算

现在,我们将计算出的值代入容斥原理公式:
|P₆₀ ∪ P₀₄ ∪ P₄₂| = 9! + 9! + 9! - 8! - 8! - 8! + 7!
= 3 × 9! - 3 × 8! + 7!

进行具体计算:

  • 9! = 362880
  • 8! = 40320
  • 7! = 5040

代入:
= 3 × 362880 - 3 × 40320 + 5040
= 1088640 - 120960 + 5040
= 967680 + 5040
= 972720

因此,在0到9的所有 10! = 3,628,800 种排列中,有 972,720 种排列至少包含“6 0”、“0 4”或“4 2”中的一个模式,这大约占总排列数的 26.8%

总结

本节课中我们一起学*了容斥原理。我们从两集合的基本形式开始,理解了为何需要减去交集以避免重复计数。然后,我们将其推广到更复杂的三集合情况,并掌握了相应的公式:|A ∪ B ∪ C| = |A| + |B| + |C| - |A ∩ B| - |A ∩ C| - |B ∩ C| + |A ∩ B ∩ C|。最后,我们通过一个数字排列计数的具体示例,完整地应用了该原理,将复杂问题分解为多个易于计算的子问题,并成功得出了答案。容斥原理是解决重叠集合计数问题的强大工具。

集合论与计数:L3.5.4:容斥原理(两个集合)🎯

在本节课中,我们将学*集合论中的一个重要工具——容斥原理。我们将从两个集合的情况开始,通过严谨的证明来理解其背后的逻辑,并初步了解如何将其推广到更多集合。

概述

容斥原理是计算多个集合的并集大小的一种方法,尤其当这些集合存在重叠时。它通过“先加后减”的方式,避免重复计算被多个集合共享的元素。本节我们将专注于两个集合的情况,并给出两种证明方法。

两个集合的容斥原理

对于任意两个集合 A 和 B,它们的并集大小可以通过以下公式计算:
[
|A \cup B| = |A| + |B| - |A \cap B|
]
这个公式的含义是:要计算 A 和 B 中所有元素的总数,我们可以先将 A 和 B 的大小相加,然后减去被重复计算了一次的、同时属于 A 和 B 的元素(即交集部分)。

上一节我们回顾了通过“计算点的次数”来直观理解容斥原理。本节中,我们将通过集合论恒等式来严格证明它。

证明方法一:利用不相交并集

证明的核心思想是将并集 (A \cup B) 分解为两个互不相交的集合,这样我们就可以直接使用求和法则。

以下是具体的证明步骤:

  1. 分解并集:集合 (A \cup B) 可以表示为两个不相交集合的并集:
    • 集合 A 本身。
    • 集合 B 中不属于 A 的部分,即 (B \setminus A)。
      因此,(A \cup B = A \cup (B \setminus A)),且 (A) 与 (B \setminus A) 不相交。

  1. 应用求和法则:由于两个集合不相交,它们的并集大小等于各自大小之和:
    [
    |A \cup B| = |A| + |B \setminus A|
    ]

  1. 关键引理:为了得到最终公式,我们需要证明一个引理:(|B \setminus A| = |B| - |A \cap B|)。

    • 我们可以将集合 B 分解为两个不相交的部分:属于 A 的部分(即 (A \cap B))和不属于 A 的部分(即 (B \setminus A))。
    • 因此,(B = (A \cap B) \cup (B \setminus A))。
    • 再次应用求和法则,得到:(|B| = |A \cap B| + |B \setminus A|)。
    • 将 ( |B \setminus A| ) 移到等式一边,即证明了引理:(|B \setminus A| = |B| - |A \cap B|)。
  2. 完成证明:将步骤3的引理代入步骤2的等式:
    [
    |A \cup B| = |A| + (|B| - |A \cap B|) = |A| + |B| - |A \cap B|
    ]
    至此,两个集合的容斥原理得证。

向多个集合的推广

理解了两个集合的情况后,我们可以将其推广到三个乃至 n 个集合。

对于三个集合 A, B, C,其容斥原理公式为:
[
|A \cup B \cup C| = |A| + |B| + |C| - |A \cap B| - |A \cap C| - |B \cap C| + |A \cap B \cap C|
]
其模式是:先加所有单个集合的大小,再减去所有两两交集的大小,最后加上所有三个集合交集的大小。

对于 n 个集合 (A_1, A_2, ..., A_n),其广义容斥原理公式如下:
[
\left| \bigcup_{i=1}^{n} A_i \right| = \sum_{\emptyset \neq S \subseteq {1,2,...,n}} (-1)^{|S|+1} \left| \bigcap_{i \in S} A_i \right|
]
这个公式的含义是:

  • 对索引集合 ({1,2,...,n}) 的每一个非空子集 S 进行求和。
  • 计算子集 S 中所有指定集合的交集大小 (\left| \bigcap_{i \in S} A_i \right|)。
  • 根据子集 S 的大小 (|S|) 来决定该项的符号:如果 (|S|) 是奇数,则符号为正(因为 ((-1)^{|S|+1} = 1));如果 (|S|) 是偶数,则符号为负(因为 ((-1)^{|S|+1} = -1))。

如何证明广义容斥原理

有多种方法可以证明这个通用公式。

  1. 数学归纳法:这是最直接的方法。以两个集合的公式为基础,假设公式对 n-1 个集合成立,然后考虑第 n 个集合的加入,并应用两个集合的容斥原理进行推导。这个过程是严谨且机械的,但可能对理解原理的本质帮助有限。

  2. 组合计数法:这是更富洞察力的方法。其核心思想是追踪并集中每个元素被计算的次数。在公式右边的求和中,一个恰好属于 k 个原始集合的元素,会被所有包含它的交集项所计数。通过分析二项式系数,可以证明该元素在公式右边恰好被计算了一次。这种方法将非正式的“先加后减”论证变得严谨,并揭示了公式与二项式定理之间的深刻联系。

总结

本节课中我们一起学*了容斥原理。我们从两个集合的基本公式出发,通过将其分解为不相交子集并利用求和法则,给出了一个严谨的证明。随后,我们了解了该原理如何推广到任意 n 个集合,并给出了通用公式。最后,我们讨论了证明通用公式的两种主要方法:数学归纳法和更具启发性的组合计数法。容斥原理是解决复杂计数问题的基础工具,理解其证明过程有助于我们更灵活地应用它。

计算机科学的数学基础:L4.1.1:树模型 🌳

在本节课中,我们将要学*概率论的基础知识,特别是如何通过构建树模型来分析和计算复杂随机事件的概率。我们将从一个经典的扑克牌问题入手,然后深入探讨著名的“蒙提霍尔问题”,以展示概率的直观理解有时会出错,而系统性的树模型方法则能提供清晰的答案。

概率的初步概念 🎲

概率论在科学、工程和社会科学中扮演着基础性角色。历史上,它起源于对赌博的分析,后来发展成为保险业和数据分析的基石。理解概率论的基本原理是现代教育的重要组成部分。

概率的第一个朴素想法是:对于一个随机实验,我们有一组可能的结果。我们感兴趣的某些结果构成一个事件。事件的概率被定义为该事件包含的结果数量除以所有可能结果的总数。

公式P(事件) = (事件中的结果数) / (所有可能结果的总数)

例如,在扑克牌中,计算拿到恰好两张J的概率。一副牌有52张,总共有 C(52, 5) 种可能的5张手牌组合。拿到两张J的组合数是:先选J的花色 C(4, 2),再从剩下的48张牌中选3张 C(48, 3)

代码/公式

总手牌数 = C(52, 5)
两张J的手牌数 = C(4, 2) * C(48, 3)
P(两张J) = [C(4, 2) * C(48, 3)] / C(52, 5) ≈ 0.04

在这个解释下,概率可以理解为:如果我们认为所有手牌出现的可能性相同,那么抽到特定手牌的频率就是其概率。

蒙提霍尔问题:一个反直觉的案例 🚪

上一节我们介绍了基于等可能结果的概率计算。本节中我们来看看一个著名的反例——蒙提霍尔问题,它说明了朴素概率模型的局限性。

蒙提霍尔是一个电视游戏节目。规则如下:

  1. 有三扇门,其中一扇后面有汽车(大奖),另外两扇后面是山羊。
  2. 参赛者先选择一扇门(例如2号门)。
  3. 主持人(知道汽车在哪里)会打开一扇参赛者未选择的、后面是山羊的门(例如3号门)。
  4. 然后,参赛者可以选择坚持最初的选择(2号门),或者到另一扇未打开的门(1号门)。

问题是:坚持和更换策略,哪个赢得汽车的概率更高?

关于这个问题曾有过激烈的公开辩论,甚至包括一些数学家。主要形成了两种对立的观点:

  • 观点一:坚持和更换策略的获胜概率相同,都是1/2。
  • 观点二:更换策略更好,获胜概率是2/3。

为了系统地解决这个争论,我们需要一个更严谨的方法来为这个随机过程建立概率模型。

构建概率树模型 🌲

面对蒙提霍尔这样的复杂问题,直觉可能不可靠。我们提出一个四步法来建立概率模型,其核心是树模型

以下是构建和分析概率模型的四个步骤:

  1. 找出样本空间:识别随机实验所有可能的结果。树结构可以帮助我们一步步分解实验过程。
  2. 确定目标事件:在所有结果中,明确哪些结果属于我们关心的事件(例如“获胜”)。
  3. 为结果分配概率:利用树的结构和逻辑,为每条路径(即每个结果)分配概率权重。
  4. 计算事件概率:将目标事件中所有结果的概率相加,得到该事件的概率。

现在,让我们将这个四步法应用到蒙提霍尔问题上,分析“总是更换”策略。

为“更换策略”建立树模型

我们按照实验步骤构建决策树:

  • 第一层(奖品位置):工作人员随机放置汽车。三个选择(门1、门2、门3)的概率各为 1/3
  • 第二层(参赛者初选):参赛者随机选择一扇门。三个选择(门1、门2、门3)的概率各为 1/3
  • 第三层(主持人开门):主持人必须打开一扇有山羊且未被参赛者选择的门。他的选择取决于前两步:
    • 如果参赛者初选就选中了汽车(例如奖品在1,选1),那么主持人可以在两扇山羊门(2和3)中随机打开一扇,每扇概率为 1/2
    • 如果参赛者初选未选中汽车(例如奖品在1,选2),那么主持人只能打开剩下的那扇山羊门(3),概率为 1

以下是获胜情况的分析(假设总是更换):

  • 如果初选就选中汽车(概率路径权重小),更换后必然失败。
  • 如果初选未选中汽车(概率路径权重大),更换后必然获胜。

通过计算树上所有路径的概率,我们可以汇总:

公式

P(更换获胜) = P(初选未中奖) = 2/3
P(坚持获胜) = P(初选中奖) = 1/3

因此,更换策略的获胜概率是2/3,而坚持策略的获胜概率只有1/3。树模型清晰地显示了,虽然某些结果路径数量相同,但它们的概率权重不同,这正是直觉容易出错的地方。

核心要点与四步法总结 📝

本节课中我们一起学*了概率论的基础和树模型的应用。

我们首先了解了概率的经典定义,即事件结果数与总结果数之比。然后,通过蒙提霍尔问题,我们发现并非所有结果都具有相同的可能性(权重),因此需要更精细的模型。

我们引入了用于分析概率问题的四步法

  1. 找出样本空间(用树模型描述过程)。
  2. 确定目标事件(哪些结果代表“赢”)。
  3. 为结果分配概率(根据逻辑为树的分支赋予概率)。
  4. 计算事件概率(将相关结果的概率相加)。

这个方法的优势在于,它用结构化的逻辑取代了容易出错的直觉,尤其适用于涉及多个步骤和条件的随机过程。记住,在概率论中,直觉是重要的,但也需要严谨的方法来验证。

计算机科学的数学基础:L4.1.3:简化的蒙提霍尔问题树 🌳

在本节课中,我们将学*如何通过构建一个更简化的概率树模型,来分析蒙提霍尔问题中“换门”策略的获胜概率。我们将看到,通过巧妙的建模,可以极大地简化分析过程,并清晰地得出结论。


上一节我们介绍了使用详尽概率树分析蒙提霍尔问题的方法。本节中我们来看看如何通过简化这个树模型,让分析过程变得更加直观和高效。

最初构建的树模型非常庞大和复杂。它完整地枚举了奖品在三个门后的所有情况、参赛者的选择以及主持人开门的所有可能。这个树具有对称结构,即奖品在门1、门2、门3后的三个子树结构完全相同。因此,我们实际上只需要分析其中一个子树,就能推断出整体的结果。

与其分析一个包含三个对称分支的庞大树,不如从一开始就构建一个更精简的模型。我们可以假设奖品固定在某个门后(例如门2),然后分析参赛者选择不同门的情况。这样,我们得到的子树如下所示:

奖品在门2
├── 参赛者选门1 (概率 1/3)
│   └── 主持人必须开空门3 (概率 1) -> 换门则赢
├── 参赛者选门2 (概率 1/3)
│   └── 主持人可开空门1或3 (各概率 1/2) -> 换门则输
└── 参赛者选门3 (概率 1/3)
    └── 主持人必须开空门1 (概率 1) -> 换门则赢

然而,一个更好的建模思路是相对化参赛者的选择。我们并不关心具体选了哪扇门,只关心参赛者的选择与奖品门之间的关系。这可以分为三种情况:

以下是三种相对情况:

  1. 参赛者选中了奖品门。
  2. 参赛者选中了“第一个”非奖品门(即按某种顺序,离奖品门最*的那个空门)。
  3. 参赛者选中了“第二个”非奖品门(即剩下的那个空门)。

每种情况的概率都是 1/3。在这种视角下,树模型可以进一步简化。特别是,当我们只关心“换门”策略的最终胜负时,许多中间步骤可以合并。

如果我们只分析“换门”策略,那么:

  • 只要参赛者最初选中的是非奖品门(上述情况2或3),那么主持人别无选择,只能打开另一扇空门,此时换门就一定会赢。
  • 如果参赛者最初选中了奖品门(上述情况1),那么无论主持人打开哪扇空门,换门都一定会输。

因此,整个实验过程可以压缩为一个极其简单的树:

初始选择
├── 选到非奖品门 (概率 = 2/3) -> 换门则赢
└── 选到奖品门 (概率 = 1/3) -> 换门则输

从这个简化模型中,我们可以直接读出结论:采用“换门”策略时,获胜的概率是 2/3。用公式表达就是:
P(换门获胜) = P(初始选择非奖品门) = 2/3


本节课中我们一起学*了如何通过构建简化的概率树模型来分析蒙提霍尔问题。核心在于,对同一个场景进行概率建模时,可能存在多种有效的模型。选择一个能够抓住问题本质、忽略不必要细节的模型,往往能让分析过程更清晰、结论更直观。简化的树模型直接揭示了“换门获胜等价于初始猜错”这一核心关系,从而高效地得出了 2/3 的获胜概率。

概率论基础:L4.1.5:样本空间 📊

在本节课中,我们将学*概率论的数学基础,即概率空间的基本定义。我们将从之前讨论的具体例子转向更抽象、更形式化的概念。

概率空间的定义

上一节我们通过树模型分析了具体问题。本节中,我们来看看支撑这些分析的抽象数学框架——概率空间。

一个概率空间由两个基本部分组成:一个样本空间和一个概率函数

样本空间

样本空间 S 是一个可数的结果集合。它旨在建模你的随机实验中所有可能发生的事情,即所有可能的结果。我们要求结果的数量是可数的。目前我们看到的例子都是有限的,但很快我们会看到需要无限(但可数)结果的例子。

概率函数

概率函数 Pr 的任务是为每个结果分配概率。它必须满足以下条件:

  • 对于样本空间 S 中的每一个结果 ω,其概率 Pr(ω) 是一个介于 0 和 1 之间(包含 0 和 1)的数。
  • 所有结果的概率之和必须等于 1。这是定义概率函数的关键条件。

用公式表示,即:

对于所有 ω ∈ S,有 0 ≤ Pr(ω) ≤ 1。
且 Σ_{ω ∈ S} Pr(ω) = 1。

一个配备了概率函数的样本空间就构成了一个概率空间。我们之前使用的树模型,其目的正是为了帮助我们确定使用哪个概率空间。在得到概率空间之前是建模部分,这非常重要,但模型的对错取决于它与现实的吻合程度以及我们的使用目的。在树模型中,叶子节点对应着结果,而我们从根节点到叶子节点推理出的分支概率,最终决定了每个结果的概率,从而构建出概率空间。

事件及其概率

另一个关键概念是事件。形式上,事件就是样本空间的一个子集。它代表你感兴趣的一组结果(例如“获胜”)。

事件 E 的概率定义非常简单:它是事件 E 中所有结果的概率之和。

用公式表示,即:

Pr(E) = Σ_{ω ∈ E} Pr(ω)

我们在分析蒙提霍尔问题和扑克手牌时已经使用了这个定义,但这是官方的一般性定义。一旦我们有了为结果分配概率的函数,就可以用它来定义事件的概率。

从这个定义可以立即推导出一个概率论的核心规则,称为求和规则

以下是求和规则的内容:

  • 如果有一系列事件 A₀, A₁, A₂, ...两两互斥的(即任意两个事件没有共同的结果),那么这些事件的并集(即至少有一个事件发生)的概率,等于各个事件概率之和。

用公式简洁地表示为:

如果对于所有 i ≠ j,有 Aᵢ ∩ Aⱼ = ∅,
则 Pr(⋃_{i} Aᵢ) = Σ_{i} Pr(Aᵢ)

这个规则我们将经常使用。它将复杂问题分解为互斥的个案,分别计算每个个案的概率后再相加,非常方便。在一些更一般的概率论方法中,这实际上被当作一条公理。但在离散情况下,它只是我们定义概率方式的一个推论。

为什么是“离散”概率?

我们研究的是离散概率,因为样本空间是可数的。这使得我们可以使用求和而非积分来处理概率。如果允许连续的概率(例如,飞镖落在一条线上某个区间的概率),就必须用积分来定义概率,其理论基础要复杂得多。对于计算机科学中的几乎所有应用,我们都不需要它,因此可以愉快地避开积分或测度论,只用求和就足够了。

其他概率规则

基于可数求和规则,可以推导出一些常用的概率论规则。

差集规则

事件 A 减去事件 B(即 A 发生但 B 不发生)的概率,等于 A 的概率减去 AB 交集的概率。

用公式表示为:

Pr(A \ B) = Pr(A) - Pr(A ∩ B)

这个规则的证明与集合基数差集规则的证明类似,直接源于概率的求和规则。

容斥原理

如果 AB 不是互斥的,那么 AB 发生的概率,等于 A 的概率加 B 的概率,再减去两者同时发生的概率。

用公式表示为:

Pr(A ∪ B) = Pr(A) + Pr(B) - Pr(A ∩ B)

证明与有限集合基数的容斥原理完全相同,并且可以推广到更多集合的情况。

布尔不等式

以下是一些有用的不等式:

  1. AB 发生的概率,总是小于或等于 A 发生的概率加上 B 发生的概率。这是容斥原理的简单推论。
    Pr(A ∪ B) ≤ Pr(A) + Pr(B)
    
  2. AB 发生的概率,总是大于或等于 A 发生的概率。
    Pr(A ∪ B) ≥ Pr(A)
    
  3. 上述不等式可以推广到可数的事件集合:一系列事件中至少有一个发生的概率,小于或等于各个事件概率之和。
    Pr(⋃_{i} Aᵢ) ≤ Σ_{i} Pr(Aᵢ)
    

总结 📝

本节课中我们一起学*了概率论的核心数学基础。关键概念是概率空间,它由一个可数的结果集合(样本空间)和一个概率函数组成。概率函数为每个结果分配一个介于0和1之间的值,并且所有结果的概率之和必须为1。我们使用树模型等工具的目标就是构建这样一个概率空间。

我们还定义了事件(样本空间的子集)及其概率(事件中所有结果的概率之和)。由此推导出了重要的求和规则(用于互斥事件)以及其他实用规则,如差集规则、容斥原理和布尔不等式。这些规则构成了离散概率计算的基础。

计算机科学的数学基础:L4.2.1:条件概率定义 📊

在本节课中,我们将要学*概率论中的一个核心概念——条件概率。条件概率描述了在已知某些信息(即某个事件已经发生)的情况下,另一个事件发生的可能性。它在保险、金融、工程乃至日常推理中都有广泛应用。

条件概率的直观理解 🤔

上一节我们介绍了概率的基本概念,本节中我们来看看条件概率。条件概率是给定某一事件发生的条件下,另一事件发生的概率。例如:

  • 保险公司想知道,考虑到客户的病史,客户再活十年的可能性有多大。
  • 投资者想知道,考虑到股票过去一个月的价格波动,其明天上涨的可能性有多大。
  • 系统工程师想知道,考虑到最*请求的速率,系统发生过载的可能性有多大。

一个简单的例子:掷骰子 🎲

让我们通过一个简单的掷骰子例子来具体理解。假设我们掷一个公*的六面骰子。样本空间是 {1, 2, 3, 4, 5, 6},每个结果的概率是 1/6

现在,如果我告诉你,我掷出的点数是奇数。在这个新信息下,我想知道掷出 1 点的概率是多少?

  • 已知点数为奇数,可能的结果只剩下 {1, 3, 5}。
  • 这三个结果可能性相同。
  • 因此,掷出 1 点的概率变为 1/3

这个额外的信息(点数为奇数)改变了我们对概率的判断。

树状图与条件概率 🌳

理解条件概率的一种方法是将其视为一个两阶段的实验。首先,我们看是否掷出奇数;然后,再看具体掷出哪个数字。

以下是描述这个过程的树状图:

  1. 第一层分支:掷出奇数的概率是 1/2(对应结果 {1, 3, 5}),掷出偶数的概率也是 1/2(对应结果 {2, 4, 6})。
  2. 第二层分支(在“掷出奇数”的前提下):
    • 掷出 1 点的概率是 1/3
    • 掷出 35 点的概率各是 1/3
    • 在“掷出偶数”的前提下,掷出 1 点的概率是 0

通过这棵树,我们可以计算任何结果的概率。例如,最终掷出 1 点的总概率是 (1/2) * (1/3) = 1/6,这与最初的结论一致。

树状图上的第二层概率,如 1/30,就是我们所说的条件概率1/3 是“在掷出奇数的条件下,掷出 1 点”的概率。

蒙蒂·霍尔问题回顾 🚪

让我们回顾之前讨论过的蒙蒂·霍尔问题,其中也隐含使用了条件概率。

在分析该问题的树状图中,分支上的标签很多都是条件概率。例如,图中 1/2 这个概率,表示“在奖品在1号门且参赛者选择了1号门的条件下,主持人打开3号门”的概率。我们在构建概率模型时,已经自然地使用了条件概率来标记树的分支。

条件概率的正式定义与乘积规则 📝

以上讨论引出了条件概率的正式定义。

定义:对于概率空间中的两个事件 AB,且 P(A) > 0,则在事件 A 发生的条件下,事件 B 发生的概率(记为 P(B | A))定义为:
P(B | A) = P(A ∩ B) / P(A)

这个定义非常直观:我们将 AB 同时发生的概率,除以 A 自身发生的概率,从而将样本空间缩小到 A 发生的范围内,再看其中 B 所占的比例。

由这个定义可以直接推导出乘积规则
P(A ∩ B) = P(A) * P(B | A)

乘积规则表明,两个事件同时发生的概率,等于第一个事件发生的概率乘以在第一个事件发生的条件下第二个事件发生的概率。

乘积规则可以推广到多个事件。例如,三个事件交集的概率为:
P(A ∩ B ∩ C) = P(A) * P(B | A) * P(C | A ∩ B)

条件概率空间 🔄

另一种理解条件概率的有用视角是:以事件 A 为条件,定义了一个新的概率空间

具体来说,我们定义一个新的概率函数 P_A(或写作 P(· | A)),其样本空间不变,但概率分配规则改变:

  • 对于不在 A 中的结果,其概率为 0(因为已知 A 发生,它们不可能发生)。
  • 对于在 A 中的结果,其新概率等于其原始概率除以 P(A)。这使得 A 本身在新空间中的概率为 1

可以验证,这个新的概率函数 P_A 满足所有概率公理,因此它本身构成一个合法的概率测度。这意味着,所有适用于普通概率的规则(如加法规则、差分规则)同样适用于条件概率。

例如,条件概率的差分规则为:
P(B \ C | A) = P(B | A) - P(B ∩ C | A)

总结 📚

本节课中我们一起学*了条件概率的核心内容:

  1. 直观概念:条件概率是在已知某事件发生的前提下,另一事件发生的概率。
  2. 正式定义:当 P(A) > 0 时,P(B | A) = P(A ∩ B) / P(A)
  3. 乘积规则P(A ∩ B) = P(A) * P(B | A),该规则是构建概率树和进行序列推理的基础。
  4. 新概率空间:以事件 A 为条件,可以诱导出一个新的、定义在相同样本空间上的概率测度 P(· | A)

理解条件概率是进行复杂概率推理、使用贝叶斯定理以及分析随机过程的关键第一步。

计算机科学的数学基础:L4.2.3:总概率定律 📊

在本节课中,我们将要学*总概率定律。这是一个重要的概率论工具,它提供了一种通过将复杂事件分解为更简单的子事件(或“情况”)来进行推理的方法。

概述

总概率定律是处理各种概率问题的基本技术。其核心思想是,通过将一个事件分解为若干个互斥且完备的子事件,我们可以更容易地计算该事件的概率。

总概率定律的直观理解

上一节我们介绍了条件概率和乘法法则,本节中我们来看看如何将它们结合起来用于分解事件。

首先,我们从集合论的角度来理解。假设在一个更大的样本空间中有一个事件 A。同时,我们有三组事件 B₁B₂B₃,它们构成了样本空间的一个“划分”。这意味着:

  1. B₁B₂B₃ 互不相交(即,它们之间没有重叠)。
  2. 它们的并集覆盖了整个样本空间(即,样本空间中的每个结果都属于且仅属于其中一个 Bᵢ)。

现在,考虑事件 AA 可以被分解为它与每个 Bᵢ 的交集部分:

  • A ∩ B₁:既属于 A 又属于 B₁ 的结果。
  • A ∩ B₂:既属于 A 又属于 B₂ 的结果。
  • A ∩ B₃:既属于 A 又属于 B₃ 的结果。

由于 B₁B₂B₃ 互不相交,这些交集 A ∩ Bᵢ 也互不相交。因此,事件 A 可以表示为这些互不相交部分的并集:

A = (A ∩ B₁) ∪ (A ∩ B₂) ∪ (A ∩ B₃)

从集合论到概率论

根据概率的加法法则,互不相交事件的并集的概率等于它们各自概率之和。因此:

Pr[A] = Pr[A ∩ B₁] + Pr[A ∩ B₂] + Pr[A ∩ B₃]

接下来,我们对每个交集项 Pr[A ∩ Bᵢ] 应用乘法法则(即条件概率公式 Pr[A ∩ B] = Pr[A | B] · Pr[B])。将其代入上式,我们得到总概率定律的标准形式:

Pr[A] = Pr[A | B₁] · Pr[B₁] + Pr[A | B₂] · Pr[B₂] + Pr[A | B₃] · Pr[B₃]

定律的一般形式

以上推导基于三个划分事件,但该定律可以推广到任意有限或可数多个划分事件的情况。

假设样本空间 S 被划分为一组事件 B₁, B₂, B₃, ...,它们满足:

  1. 互斥性:对于任意 i ≠ j,有 Bᵢ ∩ Bⱼ = ∅
  2. 完备性:所有 Bᵢ 的并集等于 S

那么,对于任意事件 A,其概率为:

Pr[A] = Σᵢ Pr[A | Bᵢ] · Pr[Bᵢ]

其中,求和符号 Σᵢ 表示对所有划分事件 Bᵢ 进行求和。

这个公式是总概率定律最常用和最有用的表述。它告诉我们,一个事件 A 的总概率,等于它在各种可能“情况” Bᵢ 下发生的条件概率,乘以这些“情况”本身发生的概率,然后将所有“情况”的结果相加。

总结

本节课中我们一起学*了总概率定律。我们了解到,该定律允许我们将一个复杂事件的概率计算,分解为在一系列互斥且完备的场景下的条件概率的加权和。其核心公式为:

Pr[A] = Σᵢ Pr[A | Bᵢ] · Pr[Bᵢ]

这是一个非常强大的工具,在接下来的内容中,我们将看到它的广泛应用。

计算机科学的数学基础:4.2.5:贝叶斯定理 🧮

在本节课中,我们将要学*条件概率的一个重要应用——贝叶斯定理。我们将通过一个诊断测试的例子,来理解如何利用已知的测试准确率,结合疾病的先验概率,来计算在得到特定测试结果后,真正患病的概率。这个定理是处理不确定性信息的有力工具。

问题引入:诊断测试的可靠性

上一节我们介绍了条件概率的基本概念,本节中我们来看看它在现实中的一个经典应用场景:分析诊断测试结果的可靠性。

假设有一种用于检测肺结核的诊断测试。这个测试声称具有超过99%的准确性。具体来说,它的属性如下:

  • 如果你患有肺结核,测试保证能检测出来,结果为阳性。
  • 如果你没有肺结核,测试在99%的情况下会正确显示阴性,但在1%的情况下会错误地显示阳性(即假阳性)。

现在,假设医生为你做了这个测试,结果是阳性。这听起来很令人担忧,因为测试的准确率很高。但我们需要从概率的角度分析:在这个“非常精确”的测试显示阳性的情况下,你真正患有肺结核的概率是多少?

定义目标概率

我们首先要明确需要计算的目标。用符号表示:

  • 设事件 TB 表示“患有肺结核”。
  • 设事件 + 表示“测试结果为阳性”。

我们想要计算的是:在已知测试结果为阳性的条件下,患有肺结核的概率。这可以写作条件概率 P(TB | +)

将已知信息转化为概率

以下是关于测试准确性的已知信息,我们可以用条件概率的语言来描述它们:

  1. 真阳性率:如果确实患病,测试结果为阳性的概率是100%。即 P(+ | TB) = 1
  2. 假阳性率:如果没有患病,测试结果为阳性的概率是1%。即 P(+ | ¬TB) = 0.01。(¬TB 表示“未患肺结核”)

此外,我们还需要一个关键信息:在没有任何测试信息的情况下,一个随机个体患肺结核的概率,即 P(TB)。这被称为先验概率。根据示例,我们假设在美国,这个概率大约是 P(TB) ≈ 1/10,000 = 0.0001

推导与计算过程

现在,我们开始计算 P(TB | +)

首先,根据条件概率的定义:
P(TB | +) = P(TB ∩ +) / P(+)

其中,分子 P(TB ∩ +) 是“患病且测试为阳性”的联合概率。我们可以再次利用条件概率定义将其展开:
P(TB ∩ +) = P(+ | TB) * P(TB)

根据已知信息,P(+ | TB) = 1,所以:
P(TB ∩ +) = 1 * P(TB) = P(TB)

接下来,计算分母 P(+),即测试结果为阳性的总概率。我们使用全概率公式,考虑“患病”和“未患病”这两种互斥的情况:
P(+) = P(+ | TB) * P(TB) + P(+ | ¬TB) * P(¬TB)

代入已知数值:

  • P(+ | TB) = 1
  • P(TB) = p (我们先用符号 p 表示)
  • P(+ | ¬TB) = 0.01
  • P(¬TB) = 1 - P(TB) = 1 - p

因此:
P(+) = 1 * p + 0.01 * (1 - p) = p + 0.01 - 0.01p = 0.99p + 0.01

现在,我们将分子和分母的结果组合起来:
P(TB | +) = P(TB) / P(+) = p / (0.99p + 0.01)

这就是我们要求的条件概率公式。现在,代入先验概率 p = 0.0001
P(TB | +) = 0.0001 / (0.99*0.0001 + 0.01) ≈ 0.0001 / (0.000099 + 0.01) ≈ 0.0001 / 0.010099 ≈ 0.0099

计算结果约为 0.99%。这意味着,即使一个准确率高达99%的测试显示为阳性,你真正患上肺结核的概率也只有大约1%。

贝叶斯定理

我们刚才的推导过程,其实就是贝叶斯定理的一个具体应用。贝叶斯定理的一般形式如下:

对于任意两个事件 A 和 B(其中 P(B) > 0):
P(A | B) = [P(B | A) * P(A)] / P(B)

在我们的例子中:

  • A 对应事件 TB(患病)
  • B 对应事件 +(测试阳性)
  • P(TB | +) 是我们想求的后验概率(得到证据后的概率)。
  • P(+ | TB)似然度(假设患病时得到该证据的概率)。
  • P(TB)先验概率(得到证据前的概率)。
  • P(+)证据的边际概率,通常通过全概率公式计算。

结果分析与实际意义

这个看似反直觉的结果(99%准确的测试只带来1%的患病确信度)原因在于:疾病的先验概率(0.01%)极低,而假阳性率(1%)相对较高。绝大多数阳性结果实际上来自庞大健康人群中的假阳性,而非极少数真正的患者。

然而,这并不意味着测试无用。虽然阳性结果后患病的绝对概率不高,但相比测试前的先验概率(0.01%),它已经提升了*100倍。这在公共卫生决策中极具价值:

假设我们有有限的医疗资源(如500万剂药物),需要分配给3.5亿人口。

  • 随机分配:你治疗到真实患者的概率极低。
  • 先测试再分配:用这个99%准确的测试筛查所有人,大约会有350万人呈阳性。如果我们用500万剂药物治疗所有阳性者,就几乎能覆盖全部约1.1万名真实患者,从而极大地提高资源利用效率。

因此,测试的价值在于它显著改变了概率,为决策提供了信息增量,而不仅仅是看最终的后验概率绝对值。

总结

本节课中我们一起学*了贝叶斯定理及其应用。我们通过一个肺结核诊断测试的例子,完整展示了如何从测试的准确率(条件概率)和疾病的普遍程度(先验概率)出发,计算出在得到特定测试结果后患病的真实概率(后验概率)。关键点在于:

  1. 高准确率的测试在罕见病诊断中,阳性预测值可能仍然很低。
  2. 贝叶斯定理 P(A|B) = [P(B|A) * P(A)] / P(B) 是融合先验知识和新证据的数学框架。
  3. 理解先验概率、似然度和证据在最终结论中的共同作用,对于做出理性判断至关重要。

概率论入门:L4.2.7:蒙提霍尔问题 🎲

在本节课中,我们将学*条件概率,并运用它来分析和解释著名的蒙提霍尔问题。我们将看到,即使是一些听起来合理的论证,也可能因为错误地应用了条件概率而得出错误的答案。通过构建概率树,我们可以清晰地理解整个游戏过程,并计算出在不同策略下获胜的正确概率。

回顾概率树 🌳

上一节我们介绍了概率树的概念,本节中我们来看看如何用它来分析蒙提霍尔问题。为了计算“换门”策略的获胜概率,我们之前构建了一个详细的概率树,它描述了奖品放置、参赛者选门以及主持人卡罗尔开门这三个步骤。

这个概率树包含了所有可能的结果,虽然比我们单纯计算换门获胜概率所需的更复杂,但它能帮助我们讨论各种事件及其概率,从而理解那些导致错误答案的论证。

分析不同的事件 🧩

现在,让我们来具体分析几个关键事件,看看不同的条件如何影响概率计算。

首先,我们来看事件“山羊在2号门后”。这对应着奖品在1号或3号门后的所有分支。在概率树的12个结果中,有8个属于这个事件。

其次,事件“奖品在1号门后”只对应概率树中的一个分支。

一个常见的错误论证

以下是导致错误结论的一个常见论证思路:

当参赛者看到卡罗尔打开了2号门(后面是山羊)后,他们需要决定是坚持原来的选择还是换门。此时,他们知道“山羊在2号门后”。于是,他们可能会计算:在已知山羊在2号门后的条件下,奖品在1号门后的概率是多少?

通过计算 P(奖品在1号门 | 山羊在2号门),我们确实会得到结果 1/2。这个论证听起来正确,并且得出了“换不换门无所谓,概率都是50%”的结论。

然而,这个论证并没有计算出“坚持”策略的真实获胜概率。为什么呢?因为参赛者掌握的信息并不仅仅是“山羊在2号门后”。

纳入更多信息

参赛者不仅知道山羊在2号门后,还知道自己最初选择了哪扇门。假设参赛者最初选择了1号门,然后得知山羊在2号门后。这是一个不同的事件:(参赛者选1号门)且(山羊在2号门后)

当我们计算 P(奖品在1号门 | 参赛者选1号门 且 山羊在2号门) 时,我们仍然会得到结果 1/2。这似乎进一步强化了“坚持和换门胜率相同”的错觉。

但这仍然不是参赛者所知的全部信息。

最关键的信息:主持人的行为

参赛者最关键的信息是:卡罗尔打开了2号门。事件“卡罗尔打开2号门”与事件“山羊在2号门后”并不完全相同,因为主持人的行为遵循特定的规则(不会打开有奖品的门)。

因此,正确的条件事件应该是:(参赛者选1号门)且(卡罗尔打开2号门)

在概率树中,这个事件只对应两个结果:

  • 一个结果的概率为 1/18(对应奖品在1号门)。
  • 另一个结果的概率为 1/9(对应奖品在3号门)。

现在,我们计算在已知参赛者选1号门且卡罗尔打开2号门的条件下,奖品在1号门(即坚持获胜)的概率:

P(奖品在1号门 | 选1号门且开2号门) = (1/18) / (1/18 + 1/9) = (1/18) / (3/18) = 1/3

这意味着,当你选择了1号门并且看到卡罗尔打开了2号门时,你最初的选择只有 1/3 的概率是正确的。因此,你应该换到另一扇未打开的门(3号门),这样获胜的概率将是 2/3

核心教训与总结 📝

本节课中我们一起学*了如何运用条件概率和概率树来精确分析蒙提霍尔问题。

我们揭示了导致“50/50”错误答案的关键原因:错误地选择了条件事件。当人们只条件于“山羊在某扇门后”时,忽略了“参赛者初始选择”和“主持人特定开门行为”这些关键信息,从而得出了误导性的结论。

核心的教训是:在进行条件概率推理时,必须确保你条件于的事件完整且精确地反映了你所掌握的所有信息。任何信息的遗漏或简化都可能导致错误的计算结果。

当你对如何定义事件感到不确定时,一个可靠的方法是退回到四步法,从头开始构建完整的概率树,枚举所有基本结果。这能帮助你避免落入此类思维陷阱。

总结:在蒙提霍尔问题中,正确的分析表明,“换门”策略的获胜概率是 2/3,而“坚持”策略的获胜概率只有 1/3。这个反直觉的结论通过严谨的概率论分析得到了清晰的解释。

概率论入门:4.3.1:独立事件 🎲

在本节课中,我们将要学*概率论中的一个核心概念——独立事件。理解独立事件对于简化复杂概率问题的分析至关重要。

概述

独立事件是指彼此之间没有相互影响的事件。处理独立事件通常更为简单,因为无需考虑事件之间复杂的相互作用。一个典型的例子是多次抛硬币:前五次抛掷的结果,通常不会影响第六次抛掷的结果。本节我们将正式定义独立事件,并探讨其关键性质。

独立事件的定义

上一节我们介绍了条件概率,本节中我们来看看如何形式化地定义“互不影响”的事件。

独立事件有两个等价的标准定义。

定义一(直观定义):事件A和B独立,当且仅当知道B发生与否,不会改变A发生的概率。用条件概率公式表示为:
P(A|B) = P(A)

定义二(乘积定义):事件A和B独立,当且仅当它们同时发生的概率等于各自概率的乘积。用公式表示为:
P(A ∩ B) = P(A) * P(B)

这两个定义是等价的,可以通过条件概率的定义进行推导。定义二有一个优点:它不要求P(B) > 0,因此适用范围更广。

独立事件的性质

了解了定义之后,我们来看看独立事件具备哪些重要性质。

以下是独立事件的一些关键性质:

  1. 对称性:如果A独立于B,那么B也独立于A。这是因为定义中的乘法和交集运算都是可交换的。
  2. 与零概率事件的关系:根据定义二,如果事件B的概率为零(P(B)=0),那么B与任何事件(包括其自身)都是独立的。
  3. 与补事件的关系:事件A独立于B,当且仅当A也独立于B的补事件(即“B不发生”的事件)。这个引理可以通过概率的差运算法则简单证明。

总结

本节课中我们一起学*了独立事件的概念。我们掌握了独立事件的两个等价定义:基于条件概率不变性的直观定义,以及基于概率乘积的运算定义。我们还探讨了独立事件的三个重要性质:对称性、与零概率事件的关系,以及与补事件的关系。理解这些内容,是分析许多随机试验(如多次抛硬币、掷骰子)的基础。

计算机科学的数学基础:L4.3.3:相互独立性 🎲

在本节课中,我们将要学*事件独立性的概念从两个事件扩展到多个事件的情况,即相互独立性。我们将通过定义、示例和公式来理解这一核心概念。

相互独立性的定义

上一节我们介绍了两个事件的独立性。本节中我们来看看当事件数量超过两个时,如何定义独立性。

直观上,如果一组事件是相互独立的,那么其中任何一个事件发生的概率,都不会因为知道其他某些事件是否发生而改变。用数学语言精确描述如下:

对于事件集合 A₁, A₂, ..., Aₙ,它们是相互独立的,当且仅当对于任意子集 I ⊆ {1, 2, ..., n},都有以下等式成立:

P(⋂_{i∈I} Aᵢ) = ∏_{i∈I} P(Aᵢ)

这意味着,任意一组事件的交集概率,等于这些事件各自概率的乘积。

一个经典示例:独立抛硬币

理解相互独立性最好的例子是多次独立抛掷一枚公*硬币。

假设我们抛掷硬币多次,定义事件 Hᵢ 为“第 i 次抛掷结果为正面”。根据独立抛硬币的模型,任何一次抛掷的结果都与其他所有抛掷的结果无关。例如,第五次抛掷出现正面的概率,不会因为第一次、第四次或第七次抛掷的结果而改变。

用条件概率公式表示就是:
P(H₅ | H₁ ∩ H₂ ∩ H₄ ∩ ¬H₇) = P(H₅)
这仅仅是相互独立性所蕴含的众多等式中的一个。

成对独立 vs. 相互独立

接下来,我们通过一个具体例子来区分“成对独立”和“相互独立”这两个重要概念。

假设我们抛掷一枚公*硬币两次。

  • 定义 H₁:第一次抛掷为正面。
  • 定义 H₂:第二次抛掷为正面。
  • 定义 O:两次抛掷中正面总数为奇数(即一次正面一次反面)。

以下是关于这些事件独立性的分析:

  1. O 与 H₁ 独立吗?
    我们来验证。样本空间为 {HH, HT, TH, TT}。
    • P(O) = P({HT, TH}) = 1/2。
    • P(H₁) = P({HH, HT}) = 1/2。
    • P(O ∩ H₁) = P({HT}) = 1/4。
      由于 P(O ∩ H₁) = 1/4 = P(O) * P(H₁),根据定义,O 与 H₁ 是独立的。同理可证 O 与 H₂ 也独立。

  1. H₁ 与 H₂ 独立吗?
    是的,因为它们是两次独立的抛掷。

  2. 那么,O、H₁、H₂ 三者相互独立吗?
    答案是否定的。相互独立要求任意子集的交集概率等于概率乘积。考虑子集 {O, H₁, H₂}:

    • P(O | H₁ ∩ H₂) = P(奇数个正面 | 两次都是正面) = 0。
    • P(O) = 1/2。
      由于 P(O | H₁ ∩ H₂) ≠ P(O),所以 O、H₁、H₂ 三者不是相互独立的。

这个例子表明,一组事件可以两两之间都独立(成对独立),但整体上却不是相互独立的。

K 阶独立性

上面的例子引出了一个更一般的概念:K 阶独立性

一组事件被称为 K 阶独立的,如果其中任意 K 个事件都是相互独立的。

  • 成对独立就是 2 阶独立
  • 相互独立(对于 n 个事件而言)就是 n 阶独立

我们可以构造一个例子:抛掷一枚公*硬币 K 次,定义 H₁ 到 Hₖ 为各次抛掷的正面事件,O 为总正面数为奇数的事件。可以证明,这 K+1 个事件中,任意 K 个都是相互独立的(即 K 阶独立),但全部 K+1 个事件放在一起却不是相互独立的(即不是 K+1 阶独立)。

验证相互独立性的复杂性

最后需要指出,严格验证 n 个事件是否相互独立是一项计算量很大的任务。

根据定义,我们需要检查对于事件集合 {A₁, A₂, ..., Aₙ} 的每一个非空子集,概率乘积公式是否成立。这总共需要检查 2ⁿ - n - 1 个等式(排除空集和 n 个单元素集)。当 n 很大时,这是不现实的。因此在实际中,我们通常根据问题的物理或逻辑背景来假设独立性,而不是通过计算来验证。


本节课中我们一起学*了:

  1. 相互独立性的正式定义:任意子集的事件交集概率等于各事件概率的乘积。
  2. 通过独立抛硬币的模型理解了相互独立性的直观含义。
  3. 区分了成对独立相互独立,并通过硬币例子看到二者不等价。
  4. 引入了更一般的 K 阶独立性 概念。
  5. 了解了验证相互独立性在计算上的复杂性。

计算机科学的数学基础:P93:L4.4.1- 更大的数字游戏 🎲

在本节课中,我们将学*概率论中的一个核心概念——随机变量。我们将通过一个有趣的“更大的数字”游戏来引入这个概念,并分析游戏中的策略与获胜概率。


游戏规则 🃏

游戏中有两个队伍。队伍一的任务是从0到7(包含0和7)中挑选两个不同的整数,分别写在两张纸的背面,然后将纸正面朝下放在桌上。队伍二的任务是随机选择一张纸,翻开查看上面的数字,然后决定是保留这个数字,还是换成另一张未知数字的纸。队伍二的最终目标是获得较大的那个数字

上一节我们介绍了游戏的基本规则,本节中我们来看看队伍二可以采取的策略。

队伍二的策略 🧠

队伍二需要一种系统性的方法来决定何时“保留”,何时“交换”。他们的策略基于一个阈值Z

  • 如果翻开的数字 ≤ Z,则视为“小”数字,选择交换
  • 如果翻开的数字 > Z,则视为“大”数字,选择保留

问题的关键在于如何选择阈值Z。如果固定一个Z(例如Z=3),队伍一就能通过总是选择两个都小于或等于Z(或都大于Z)的数字来抵消队伍二的优势,使队伍二的获胜概率仅为50%。

因此,队伍二需要引入随机性。他们应该随机地选择Z,Z可以是0到6(包含0和6)中的任意一个整数,每个数字被选中的概率相等(1/7)。这样,队伍一就无法预测并针对特定的Z来制定策略。

获胜概率分析 📊

现在我们来分析队伍二采用随机阈值策略时的获胜概率。假设队伍一挑选的两个数字为lowhigh,且low < high

根据随机选择的阈值Z与lowhigh的关系,可以分为三种情况:

以下是三种可能的情况分析:

  1. 情况M(中间情况)low ≤ Z < high

    • 此时阈值Z能正确区分大小。
    • 如果翻开的是low(≤ Z),队伍二会交换,得到high并获胜。
    • 如果翻开的是high(> Z),队伍二会保留,并获胜。
    • 在此情况下,队伍二获胜的概率为1
    • 由于lowhigh至少相差1,Z落入这个区间的概率至少为1/7
  2. 情况H(Z偏大)Z ≥ high

    • 此时两个数字对队伍二来说都显得“小”(因为都≤ Z),队伍二总是选择交换。
    • 交换后,队伍二有50%的概率拿到high(即最初没翻到的那张)。
    • 在此情况下,队伍二获胜的概率为1/2
  3. 情况L(Z偏小)Z < low

    • 此时两个数字对队伍二来说都显得“大”(因为都> Z),队伍二总是选择保留。
    • 保留时,队伍二有50%的概率最初就翻到了high
    • 在此情况下,队伍二获胜的概率为1/2

计算总获胜概率 🧮

我们可以使用全概率公式来计算队伍二的总体获胜概率。设P(赢)为队伍二获胜的概率。

根据全概率公式:
P(赢) = P(赢 | M) * P(M) + P(赢 | 非M) * P(非M)

代入我们分析的值:

  • P(赢 | M) = 1
  • P(M) ≥ 1/7
  • P(赢 | 非M) = 1/2
  • P(非M) ≤ 6/7

因此:
P(赢) ≥ 1 * (1/7) + (1/2) * (6/7) = 1/7 + 3/7 = 4/7

结论:无论队伍一选择哪两个数字,队伍二采用此随机策略的获胜概率至少为4/7(约57.1%),高于50%。

更有趣的是,队伍一也可以采用一个随机策略(例如随机地选择两个数字)来确保队伍二的获胜概率至多为4/7。因此,当双方都采用最优策略时,这个游戏的“价值”就是4/7

与随机变量的关联 🔗

这个游戏自然地引出了随机变量的概念。简单来说,随机变量是一个由随机过程产生的数值。

在游戏中,我们看到了多个随机变量的例子:

  • 阈值Z:由队伍二随机生成,取值范围是{0, 1, 2, ..., 6},每个值概率为1/7。
  • 被翻开的牌的数字:如果队伍一也随机选数,且队伍二随机选牌,那么这个数字本身也是一个随机变量。
  • 较大的数字(high)和较小的数字(low):如果队伍一随机选择,它们也是随机变量。

这些由游戏中的随机过程(如“随机选择”、“随机决定”)所产生的数值,都是随机变量的具体体现。


本节课中我们一起学*了“更大的数字”游戏,并通过策略分析得出了队伍二的最优获胜概率。更重要的是,我们通过这个生动的例子,直观地理解了随机变量这一概率论基础概念——它本质上就是随机试验结果的数值化描述。在接下来的课程中,我们将对随机变量进行更正式的定义和深入探讨。

计算机科学的数学基础:4.4.2:随机变量与独立性 🎲

在本节课中,我们将要学*随机变量的正式定义,以及随机变量之间独立性的概念。我们将从直观的例子入手,逐步过渡到形式化的数学定义,并通过具体的例子来加深理解。

随机变量的直观概念

上一节我们介绍了概率论中的基本事件。本节中,我们来看看如何用数值来量化随机过程的结果,这就是随机变量。

随机变量是由随机过程产生的一个数值。以下是一些典型的例子:

  • 系统崩溃时间:观察一个系统,记录从现在到下一次系统崩溃的小时数。这个时间是一个由系统是否工作的随机过程产生的数值。
  • 显示器坏点数量:在制造显示器时,数百万像素中可能出现坏点。坏点的数量是由制造过程中不可预测的随机性产生的。
  • 盖革计数器读数:盖革计数器在一秒内检测到的α粒子数量,在物理学中被建模为一个随机数,它服从某种分布,但每秒的读数并不相同。
  • 抛硬币正面次数:抛掷一枚硬币n次,出现正面的次数是一个标准的随机变量。

随机变量的形式化定义

了解了直观概念后,我们现在给出随机变量的精确定义。

形式上,随机变量是一个将样本空间中的结果映射到实数的函数。样本空间中的结果是随机实验的可能结果,每个结果有其概率。随机变量将这些结果转化为一个实数,这个实数被视为该结果产生的数值。

因此,随机变量本质上是一个函数,记作 R: S → ℝ,其中S是样本空间,ℝ是实数集。它通常是一个实值函数,但也可以是整数值或其他子集。

从直观上看,随机变量R将一系列形如“R等于某个值a”的事件打包在一起。如果我们知道了所有“R = a”事件的答案,就掌握了随机变量所包含的信息。

随机变量的独立性

由于随机变量可以定义事件,事件独立性的概念可以直接推广到随机变量上。

一组随机变量 R₁, R₂, ..., Rₙ 被称为相互独立的,当且仅当由它们定义的任何事件集合都是相互独立的。更具体地说,对于所有可能的取值 a₁, a₂, ..., aₙ,以下等式成立:

Pr[R₁ = a₁ ∧ R₂ = a₂ ∧ ... ∧ Rₙ = aₙ] = Pr[R₁ = a₁] × Pr[R₂ = a₂] × ... × Pr[Rₙ = aₙ]

这意味着,知道其中一些随机变量的取值,不会影响其他随机变量取值的概率。

示例:判断独立性

让我们通过一个具体例子来实践。考虑抛掷三枚公*硬币的实验。定义两个随机变量:

  • C:出现正面的次数(取值0, 1, 2, 3)。
  • M:指示三枚硬币结果是否一致(全正或全反为1,否则为0)。

CM是否独立?答案是否定的。因为事件“C ≥ 1”(至少有一个正面)和事件“M = 1”(三枚一致)都有正概率,但事件“C ≥ 1 且 M = 1”等价于“三枚全是正面”,其概率为1/8。然而,Pr[C ≥ 1] × Pr[M = 1] = (7/8) × (1/4) ≠ 1/8。因此,它们不满足独立性的乘积公式,故不独立。

指示变量

指示变量是一个非常重要的概念,它建立了事件与随机变量之间的桥梁。

对于任何事件A,其指示变量 I_A 定义如下:
I_A = 1, 如果事件A发生。
I_A = 0, 如果事件A不发生。

通过指示变量,我们可以将事件视为特殊的随机变量(0-1值)。一个关键的性质是:两个事件A和B是独立的,当且仅当它们的指示变量 I_A 和 I_B 是独立的。这个性质的证明是一个很好的练*。

示例:指示变量的独立性

再次考虑抛三枚硬币。定义:

  • O:事件“出现奇数个正面”。
  • M:事件“三枚硬币结果一致”(其指示变量即之前的M)。

I_O(O的指示变量)和M是否独立?尽管两者都依赖于全部三枚硬币的结果,但事实上它们是独立的。验证这一点需要检查所有可能的取值组合((0,0), (0,1), (1,0), (1,1))是否都满足独立性的乘积公式。这是一个重要的练*。

独立性的进一步性质

如果随机变量R独立于S,那么R也独立于S的任何函数。也就是说,对于任意(全)函数 fR 独立于 f(S)。这直观地表明,R独立于关于S的任何信息。

独立性概念可以推广到K阶独立。一组随机变量是K阶独立的,如果其中任意K个变量都是相互独立的。特别地,当K=2时,我们称之为两两独立

两两独立之所以被单独强调,是因为在许多重要应用中,两两独立性就足够了,而且验证两两独立比验证相互独立要容易得多(需要检查的等式更少)。

示例:两两独立

考虑抛掷K枚公*硬币。令 H_i 为第i枚硬币出现正面的指示变量(i从1到K)。此外,定义 O 为出现奇数个正面的事件,它可以表示为 O = (Σ_{i=1}^K H_i) mod 2

可以证明,这 K+1 个随机变量(K个H_i和O)是K阶独立的,即任意K个都是相互独立的。特别地,它们是两两独立的。我们在之前的事件版本中讨论过这个例子,现在可以用随机变量的语言重新表述。


本节课中我们一起学*了随机变量的形式定义,理解了它本质上是一个从样本空间到实数的函数。我们重点探讨了随机变量独立性的概念,其核心是它们定义的事件满足概率乘积公式。我们还介绍了指示变量这一有力工具,它将事件与随机变量联系起来。最后,我们了解了K阶独立,特别是两两独立的意义,这将在后续的应用中发挥作用。

计算机科学的数学基础:L4.4.4:随机变量 - 均匀分布与二项分布 📊

在本节课中,我们将学*两种在概率论中极为常见且基础的随机变量:均匀随机变量和二项式随机变量。我们将了解它们的定义、性质以及如何用概率密度函数和累积分布函数来描述它们。

均匀随机变量 🎲

上一节我们介绍了随机变量的基本概念,本节中我们来看看均匀随机变量。均匀随机变量意味着它所取的所有可能值都具有相等的概率。

例如,一个随机变量 Z 可以取从 0 到 6(包含)的所有整数值,每个值出现的概率都是 1/7。这是一个均匀随机变量的基本例子。

以下是其他均匀随机变量的例子:

  • 如果 D 是一个公*的六面骰子的结果,那么它出现 1、2 或 6 的概率都是 1/6。
  • 一个四位数的彩票号码,其四个数字都是随机独立选择的,可能值从 0000 到 9999。彩票最终结果为 0000 的概率,与结果为 1111 或 9999 的概率相同,都是 1/10000。

现在,让我们证明一个后续会有用的小引理。假设 R1, R2, R3 是三个相互独立的随机变量,其中 R1 是均匀分布的。那么,每一对相等的事件是相互独立的。具体来说,事件 “R1 = R2” 独立于事件 “R2 = R3”,也独立于事件 “R1 = R3”。

直观的论证是:因为 R1 是均匀的且独立于 R2 和 R3,所以 R1 等于任何特定值的概率是固定的。无论 R2 和 R3 取什么值(例如,无论 R2 是否等于 R3),R1 恰好等于 R2 当前值的概率仍然是那个固定的值。因此,这些相等事件是成对独立的(尽管它们不是三方独立的)。

二项式随机变量 🔢

从均匀随机变量转向二项式随机变量,它们可能是最重要的随机变量例子之一,无处不在。

二项式随机变量的最简单定义是:进行 n 次相互独立的试验(例如抛硬币),每次试验成功的概率为 p。它有两个参数:试验次数 n 和单次成功概率 p。

例如,设 n=5, p=2/3。考虑一个特定的抛掷序列:正、反、反、正、正。由于每次抛掷独立,这个特定序列出现的概率是每次结果的概率乘积:
P(正) * P(反) * P(反) * P(正) * P(正) = p * (1-p) * (1-p) * p * p = (2/3)^3 * (1/3)^2

更一般地,在 n 次试验中,恰好出现 i 次成功的概率,等于:

  • 任何一个指定的、恰好有 i 次成功的序列出现的概率:p^i * (1-p)^(n-i)
  • 乘以所有这样的序列的数量,即从 n 个位置中选择 i 个位置放置成功:C(n, i)(组合数)

因此,我们得到二项式分布的概率公式:

公式:P(成功次数 = i) = C(n, i) * p^i * (1-p)^(n-i)

这是一个非常基本的公式,其中 i 的取值范围是从 0 到 n 的整数。

概率密度函数与累积分布函数 📈

为了抽象地描述随机变量的行为,我们引入两个关键函数。

概率密度函数 描述了随机变量取每一个特定值的概率。

  • 对于二项式随机变量,其 PDF 在值 i 上就是上述公式:f(i) = C(n, i) * p^i * (1-p)^(n-i)
  • 对于在集合 U 上的均匀随机变量,其 PDF 在 U 中任意值 v 上是常数:f(v) = 1 / |U|(其中 |U| 是集合 U 的大小)。

累积分布函数 描述了随机变量小于或等于某个值的概率。

  • CDF 在点 a 的值定义为:F(a) = P(R ≤ a)

PDF 和 CDF 是等价的,知道其中一个可以推导出另一个。它们的关键优势在于,一旦我们抽象到 PDF 和 CDF,就无需再考虑底层的样本空间。这些函数本身包含了关于随机变量行为的所有重要信息。这使得许多分析可以基于分布本身进行,从而适用于所有具有相同分布的随机变量,无论其背后的具体实验是什么。

总结 🎯

本节课中我们一起学*了:

  1. 均匀随机变量:所有可能结果等可能发生。
  2. 二项式随机变量:描述 n 次独立伯努利试验中成功次数的分布,其核心概率公式为 P(X=i) = C(n, i) * p^i * (1-p)^(n-i)
  3. 描述工具:我们引入了概率密度函数累积分布函数 来抽象地描述随机变量的分布特性,这使我们能脱离具体样本空间来分析和理解随机变量。

理解这些基本分布及其描述方式是学*更复杂概率模型的重要基石。

计算机科学的数学基础:L4.5:期望值 🎲

在本节课中,我们将学*概率论中的一个核心概念——期望值。期望值是随机变量所有可能取值的加权*均,它为我们提供了一种量化随机过程“*均”结果的方法。我们将从赌博游戏入手,直观理解期望值,然后给出其精确定义,并探讨其重要性质,如线性性和乘积规则。

从赌博游戏说起 🎰

我们经常询问*均值,在随机变量的语境下,这个概念被抽象为一个美妙的概念——随机变量的期望值

让我们从一个激发兴趣的例子开始,这个例子通常来自赌博。有一种在赌场里玩的游戏,叫做“嘉年华骰子”。游戏规则是:你有三颗公*的骰子,你先从1到6中选一个你最喜欢的数字。然后你掷出这三颗骰子,每颗骰子出现任何给定数字的概率都是1/6。奖金规则如下:每有一个骰子与你选的数字匹配,你就赢得1美元。如果没有一个骰子显示你选的数字,你就输掉1美元。

让我们举个例子。假设你最喜欢的数字是5。你向庄家宣布这个数字,然后开始掷骰子。

  • 如果掷出的数字是2、3和4,没有5,你输掉1美元。
  • 如果掷出的数字是5、4、6,有一个5,你赢得1美元。
  • 如果掷出的数字是5、4、5,有两个5,你赢得2美元。
  • 如果全是5,你赢得3美元。

关于这个游戏的基本问题是:这是一个公*的游戏吗?值得玩吗?我们如何思考这个问题?我们将从概率的角度来思考。

计算游戏的概率分布 📊

让我们思考掷出“没有5”的概率。如果5是我最喜欢的数字,那么我没有掷出5的概率是多少?第一颗骰子不是5的概率是5/6,第二颗和第三颗也是。由于骰子掷出是独立的,所以没有5的概率是 (5/6)³,即 125/216。我写成分数形式是为了方便比较。

那么,掷出“一个5”的概率是多少?任何包含一个5的特定掷骰序列的概率是 (5/6) × (5/6) × (1/6)。并且,在三个位置中选一个出现5,其他位置不是5的序列有 C(3,1) 种。类似地,对于“两个5”,有 C(3,2) 种方式选择出现5的两个位置,概率为 C(3,2) × (5/6) × (1/6)²。“三个5”的概率就是 (1/6)³。

我们可以轻松计算这些概率。让我们把它们列在表格里:

  • 0次匹配 的概率是 125/216,此时我输掉1美元。
  • 1次匹配 的概率是 75/216,此时我赢得1美元。
  • 2次匹配 的概率是 15/216,此时我赢得2美元。
  • 3次匹配 的概率是 1/216,此时我赢得3美元。

期望收益的计算 💰

现在我可以问:我期望赢多少?假设我玩了216次游戏,并且结果完全按照这些概率分布,那么我期望:

  • 大约有125次是0次匹配(即输1美元)。
  • 大约有75次是1次匹配(即赢1美元)。
  • 大约有15次是2次匹配(即赢2美元)。
  • 大约有1次是3次匹配(即赢3美元)。

我的*均收益将是:[125 × (-1) + 75 × 1 + 15 × 2 + 1 × 3] / 216。计算结果约为 -17/216 美元,即大约 -0.08美元(-8美分)。

所以,我*均每次游戏损失约8美分。这不是一个公*的游戏,它对我有偏见。如果我玩得足够久,*均下来我每次游戏会稳定地损失约8美分。

因此,我们总结为:你期望损失8美分,意思是你的*均损失是8美分。如果你反复玩这个游戏,就会出现这种现象。重要的是要注意,你从未在任何单次游戏中实际损失8美分。“期望损失8美分”这个概念永远不会在单次游戏中发生,它只是你的*均损失。每次游戏你只会损失1美元,或赢得1美元、2美元、3美元,根本不会出现8美分。

期望值的正式定义 📝

上一节我们通过具体游戏理解了期望值的直观含义,现在让我们抽象出随机变量期望值的正式定义。

随机变量R是一个以不同概率取不同值的东西。它的期望值定义为它的*均值,其中不同的值按其概率加权。

我们可以将其写成一个精确的公式。随机变量R的期望值定义为,对其所有可能取值V求和:V × P(R = V)

公式: E[R] = Σ (v ∈ 所有可能值) [ v * P(R = v) ]

这就是随机变量期望值的基本定义。这里求和成立是因为我们假设了可数样本空间,R只定义在可数个结果上,这意味着它只能取可数个值。所以我们是在对所有R可能取的值进行可数求和。

我们刚刚得出的结论是,嘉年华骰子游戏的期望收益是 -17/216。对照这个期望值的正式定义,以及定义为“你在一次嘉年华骰子游戏中赢多少钱”的随机变量,结果就是那个*均值 -17/216。

期望值的另一种定义 🔄

有一个在证明中很有用的技术性结果指出,期望值还有另一种表达方式:它也可以表示为,对样本空间中所有可能的结果求和:随机变量在该结果下的值 × 该结果的概率

公式: E[R] = Σ (ω ∈ 样本空间) [ R(ω) * P(ω) ]

这与“对所有值求和:值 × 该值的概率”是另一种定义。这两个定义等价并非完全显而易见。这种形式的定义在一些证明中技术上很有帮助,尽管在应用中使用不多。证明这个等价性是一个不错的练*。

我们来推导一下这个等价性。记住,记号 [R = v] 描述了随机变量取值为v的事件,根据定义,这个事件是满足该性质的结果集合,即 { ω | R(ω) = v }。因此,P(R = v) 就是该事件中所有结果的概率之和。

从期望的标准定义开始:E[R] = Σ_v [ v * P(R = v) ]

  1. P(R = v) 替换为 Σ_{ω: R(ω)=v} P(ω)
  2. 将v分配到内层求和:得到 Σ_v Σ_{ω: R(ω)=v} [ v * P(ω) ]
  3. 对于这些结果ω,有 R(ω) = v,所以可以将v替换为 R(ω),得到 Σ_v Σ_{ω: R(ω)=v} [ R(ω) * P(ω) ]
  4. 现在,对外层所有可能的v求和,并对每个v求所有满足 R(ω)=v 的ω的和,这等价于对所有可能的结果ω求和。因此,最终得到 Σ_ω [ R(ω) * P(ω) ]

证明完成。这个推导涉及大量对求和项的重新排列。

期望值与*均值的关系 📈

我们说过期望值是*均值的一种抽象,但它与*均值的联系比那更紧密。

举个例子:假设你有一堆批改好的试卷。你随机抽取一份。让S代表随机抽取试卷的分数。我将“从一堆试卷中随机抽取一份”这个随机过程定义为一个随机变量S。“随机抽取”意味着均匀抽取。所以,S本身不是均匀随机变量,但我以等概率抽取试卷,而它们有不同的分数。因此,结果是等概率的,但S不是,因为可能有很多相同分数的试卷。

S是由这个“随机抽取试卷”过程定义的随机变量。那么,你可以验证,S的期望值恰好等于试卷的*均分数。这正是考试结束后学生通常想知道的东西:*均分是多少?实际上,*均分通常不如中位数(中间分数)信息量大,但人们总是想知道*均值。

*均值可能信息量不大的原因是它有一些奇怪的性质,我稍后会说明。但这里的重点是,我们通过定义一个基于随机抽取试卷的随机变量,得到了考试的*均分数。这是一个通用过程:我们可以通过估计随机变量的期望值,来估计某个事物总体中的*均值,这个随机变量基于从我们要计算*均值的事物中随机抽取元素。这被称为抽样。这是概率论的一个基本思想:我们能够通过将*均值的计算抽象为定义随机变量并计算其期望值,来掌握*均值。

期望值的性质:线性性 ✨

到目前为止,我们通过定义或巧妙的方法(如生成函数)计算期望值。现在,我们将介绍一个使期望计算变得非常简单的性质,它绕过了许多我们迄今为止使用的巧妙方法,即:期望是线性的

这意味着,如果你有两个随机变量R和S,以及两个常数a和b,那么期望函数是线性的。即,你取R和S的线性组合 aR + bS,其期望值等于对应期望的线性组合。

公式: E[aR + bS] = a * E[R] + b * E[S]

这是一个绝对基本的公式,你应该熟练掌握。记住,它不仅适用于任意有限多个变量,在一定的收敛条件下,甚至可以扩展到可数个变量的和。但今天我们先讨论两个随机变量的情况。

使其如此强大和有用的关键在于,这个事实与独立性无关。无论R和S是否独立或相等,都不重要。这个线性性始终成立。

证明并不特别有启发性,它只是对求和项进行操纵和重新排列。但让我们完成这个练*。我们感兴趣的是随机变量 aR + bS 的期望值。根据期望的定义(对结果求和的形式),它是 Σ_ω [ (aR(ω) + bS(ω)) * P(ω) ]。展开后,我们可以将求和分成两部分:a * Σ_ω [ R(ω) * P(ω) ] + b * Σ_ω [ S(ω) * P(ω) ]。根据定义,这等于 a * E[R] + b * E[S]。证明完成。

指示器随机变量的期望 🎯

在利用线性性之前,我们先做一个非常简单但非常重要的观察:关于指示器随机变量的期望。

记住,I_A 是一个随机变量,如果事件A发生则等于1,如果A不发生则等于0。那么 I_A 的期望值是多少?根据定义,它是 1 * P(I_A = 1) + 0 * P(I_A = 0)。我们可以忽略第二项(0乘以某数)。P(I_A = 1) 恰好就是 P(A)。所以我们得到了基本公式:

公式: E[I_A] = P(A)

记住这个公式,我们马上会多次用到它。

应用线性性:n次抛硬币的期望正面数 🪙

让我们回到“n次抛硬币的期望正面数”这个问题,我们已经见过至少两种方法(生成函数论证和使用全期望的递归论证)。现在,我们将使用线性性非常优雅地解决它。

H_i 为第i次抛掷出现正面的指示器变量。那么,总正面数这个随机变量,就等于第一次抛掷出现正面的指示器变量,加上第二次的,一直加到第n次的。

公式: 总正面数 = H_1 + H_2 + ... + H_n

突然之间,我想要计算的随机变量变成了n个随机变量(实际上是n个指示器变量)的和。根据线性性,总正面数的期望等于这些指示器变量期望的和:E[H_1] + E[H_2] + ... + E[H_n]

每次抛掷出现正面的期望是多少?由于抛掷是独立的,每次的期望就是出现正面的概率p。所以,总和是 n * p

公式: E[总正面数] = n * p

这是我们之前用其他方法推导出的公式,现在它几乎不费吹灰之力就优雅地得出了,唯一的巧妙之处在于将正面数表达为指示器变量之和。

更多线性性的应用示例 🎩

让我们看一个相关的例子:问在n个人寄存帽子后,帽子被混乱归还时,期望有多少人拿回自己的帽子。

假设帽子被无能的员工完全打乱,使得每个人拿回自己帽子的概率是1/n(即所有n!种排列等可能)。我们问,在所有排列等可能的情况下,期望有多少人拿回自己的帽子?

R_i 为指示器变量,表示第i个人是否拿回了自己的帽子。注意,R_iR_j 并不独立。例如,如果我知道R1拿回了帽子,那么R2拿回自己帽子的概率就从1/n变成了1/(n-1),因为1号帽子已经不在选择池中了。所以它们不是独立的。

然而,独立性对线性性不重要。所以我仍然可以说,归还帽子数的期望等于每个人拿回帽子指示器变量之和的期望。根据线性性,这等于每个指示器变量期望的和。每个 E[R_i] 我们算出来是1/n,共有n个,所以总和是 n * (1/n) = 1

结论: 当所有帽子被打乱且所有排列等可能时,我期望有1个人拿回自己的帽子。

现在让我们稍微改变一下情景,考虑一个中式宴会。传统上,9个人围坐在一张有转盘(懒人转盘)的圆桌旁,每个人面前有一道菜。假设有n个人,n道不同的菜。现在我们随机旋转转盘。问:旋转后,期望有多少人面前还是原来那道菜?

R_i 表示第i个人面前还是原来那道菜。现在,这些 R_i 比之前的帽子例子依赖性更强:它们要么全是1(如果转盘转回原位),要么全是0(如果转盘偏移了)。这些变量是尽可能依赖的。

但这没关系,因为线性性仍然成立。 这意味着,关于“拿回原来那道菜的人数期望”的论证仍然有效,期望值仍然是1,尽管所有的 R_i 都相等。

以上就是关于期望线性性的美妙规则,它无论变量是否独立都成立。

独立随机变量的乘积规则 ✖️

对于乘积,有一个规则,但它要求独立性。独立乘积规则指出:如果两个随机变量X和Y独立,那么它们乘积的期望等于它们期望的乘积。

公式: 若 X 与 Y 独立,则 E[X * Y] = E[X] * E[Y]

如果多个变量相互独立,这也扩展到多个变量。

证明是通过重新排列定义X*Y期望的和式中的项来完成的。关键步骤在于一开始利用独立性,将 P(X=x ∧ Y=y) 拆分为 P(X=x) * P(Y=y)

需要注意的常见错误 ⚠️

让我以人们常犯的几个错误作为结束。

首先,不要忘记独立性是期望乘积规则的关键条件。它在某些变量相关的情况下也可能成立,但这不是必要条件,而是充分条件。你需要某种条件才能使乘积规则成立。让我们举个简单的例子来记住如果独立性不成立会发生什么。

假设我有一个随机变量X,它以相等的概率取正值和负值(例如,以1/2概率取1,以1/2概率取-1;或者以某种对称方式取π和-π等)。这样的X关于0对称,其期望值E[X]为0,因为正负项相互抵消。另一方面,如果我取X²,那么所有这些正负值都变成正的,所以E[X²]是正的。因此,E[X] * E[X] = 0,小于E[X²]。这说明了当没有类似独立性的条件时,乘积规则可能失败。

第二个错误更有趣,人们可能会陷入其中,因为有一种诱惑认为,如果乘积规则对独立成立,那么倒数规则也应该成立。即,你可能会认为当X和Y独立时,E[X / Y] = E[X] / E[Y]。但这是不正确的。即使它们独立,E[X/Y] 通常也不等于 E[X] / E[Y]。反例是:如果X是常数1,那么 E[1/Y] 通常不等于 1 / E[Y]。一些知名人士曾犯过这个错误,你不应该犯。

总结 📚

在本节课中,我们一起学*了概率论的核心概念——期望值

  1. 我们从具体的“嘉年华骰子”游戏入手,直观理解了期望值作为长期*均结果的含义。
  2. 我们给出了期望值的两种等价数学定义:基于值域的加权和 E[R] = Σ v * P(R=v),以及基于样本空间的和 E[R] = Σ R(ω) * P(ω)
  3. 我们探讨了期望值与*均值(如考试*均分)的紧密联系,以及如何通过抽样用期望估计总体*均。
  4. 我们学*了期望值最重要的性质之一:线性性。即 E[aR + bS] = aE[R] + bE[S],且该性质不要求R和S独立。
  5. 我们掌握了指示器随机变量期望的简单公式:E[I_A] = P(A)
  6. 利用线性性和指示器变量,我们优雅地解决了“n次抛硬币期望正面数”和“帽子归还问题”等多个例子。
  7. 对于独立的随机变量,我们介绍了乘积规则E[X*Y] = E[X] * E[Y]
  8. 最后,我们指出了两个常见错误:忽略乘积规则对独立性的要求,以及错误地将倒数规则与乘积规则类比。

期望值是分析和理解随机现象的有力工具,其线性性使得许多复杂问题的计算变得简单直接。

计算机科学的数学基础:L4.6:期望的偏离:马尔可夫与切比雪夫界 🎯

在本节课中,我们将要学*随机变量偏离其期望值的概率。我们将探讨两个重要的概率不等式:马尔可夫界和切比雪夫界。它们能帮助我们理解,即使单次实验的结果几乎不可能恰好等于期望值,但大量实验的*均结果会如何围绕期望值波动。

从期望值谈起 📊

上一节我们介绍了期望值及其最重要的性质——线性性。现在,让我们退一步思考:期望值究竟意味着什么?我们为何关心它?我们有一个直观的想法:如果你对一个随机变量进行足够多次的实验,其长期*均值将接*其期望值。本节中,我们将尝试让这个想法变得更精确。我们将讨论“偏离期望值”这一主题,或者说,期望值的真正含义是什么。

让我们看一个熟悉的例子来把握我们感兴趣的具体概念。假设我抛一枚公*的硬币101次。由于可能的结果是从0到101,中间值就是期望值,所以期望的正面次数是50.5次。然而,我们永远不会恰好得到50.5次正面,因为不可能抛出一半的正面。所以,我们并不“期望”单次实验的结果恰好等于期望值。期望值是我们预期在*均意义上会出现的结果。

我们可以问:得到尽可能接*期望值的概率是多少?例如,恰好得到50次正面的概率大约是1/13。或者,得到50或51次正面(即在期望值±1范围内)的概率大约是1/7。如果我们抛更多的硬币,比如1001次,期望的正面次数是500.5次。恰好得到500次正面的概率是1/39,在期望值±1范围内的概率大约是1/19。这些概率比之前(100次抛掷时)降低了。所以,随着抛掷次数的增加,正面次数落在期望值某个固定距离(比如±1)内的概率实际上降低了。

但是,当我们开始看百分比时,情况会好转。对于1001次抛掷,落在期望值1%范围内的概率是多少?1001的1%大约是10。所以,我们问的是落在490到510次正面之间的概率。这个概率大约是49%,几乎是50%。所以,当我抛1001次硬币时,实际上有大约50%的机会落在期望值的1%范围内。

因此,我们可以开始说,当我们试图解释期望值的含义时,如果我们用 μ 表示随机变量 R 的期望值(这只是为了在公式中更美观),我们问的基本问题有两个:

  1. 随机变量 R 远离其期望值 μ 的概率是多少?即 P(|R - μ| ≥ x)
  2. *均偏离是多少?即偏离距离的期望值 E(|R - μ|)

当然,我们试图用偏离距离的期望值来解释期望值的含义,这里有一点循环论证。但让我们暂且接受并继续。

理解偏离:两个骰子的例子 🎲

让我们看一个例子来具体化这些概念。考虑两个具有相同期望值的骰子。绿色骰子是一个标准的公*骰子,数字1到6出现的概率相等,其期望值正好是1和6的中点,即3.5。现在,假设我们看一个灌铅的骰子(骰子2),它只掷出1或6,且概率相等。根据同样的推理,它的期望值也是3.5。这是两个不同的随机变量:一个以等概率取1到6的值,另一个只取1和6两个值,但它们有相同的期望值。

那么,如何捕捉它们的区别呢?如果我们看公*骰子到其期望值的*均距离,我断言是1.5。而灌铅骰子到其相同期望值的*均距离实际上是2.5。事实上,第二个骰子总是恰好偏离其期望值2.5。

让我们看看概率质量函数来理解发生了什么。这是公*骰子的PMF。在1到6上,每个绿色柱子的高度是1/6,它们的总和为1,表示公*骰子以等概率取1到6中的某个值。期望值正好在中间的3.5处。这些点到期望值的*均距离:你可以看到,有1/3的时间(取值为2和5时)距离是1.5;另外1/3的时间(取值为1和6时)距离是2.5;剩下的1/3时间(取值为3和4时)距离是0.5。这些距离*均下来是1.5。所以,公*骰子偏离其期望值的*均距离是1.5。另一方面,对于灌铅骰子,正如我们所说,它总是恰好偏离其期望值2.5,这意味着它的期望偏离距离也是2.5。

通过这个简短的例子,我们可以看到,尽管这两个分布(两种骰子)有相同的期望值,但其中一个更可能且具有更大的期望偏离距离。其寓意是:仅凭均值本身并不能很好地预测随机变量的行为。正如你可能想到的,一个参数、一个数字无法捕捉PMF的形状,而PMF能提供关于随机变量值分布的更完整信息。我们需要比期望值更多的信息,其中一个有价值且信息量仍远小于整个PMF形状的额外信息,就是了解它可能偏离其均值的程度。

马尔可夫界:一个简单而强大的起点 📉

关于随机变量显著偏离其期望值的最简单界限,是由一位名叫马尔可夫的俄罗斯概率论学家提出的,这就是我们将要讨论的马尔可夫界。让我们用一个在MIT背景下令人难忘的IQ例子来说明。IQ(智商)是19世纪末(也可能是20世纪初)发明的概念,旨在打破哈佛大学聘用富裕校友子女的模式,其想法是基于成绩录取,并采用一种不依赖于社会阶层的客观能力衡量标准。心理学家们最初设计的智商*均值为100。

现在,让我们问一个极端的问题:在精英大学周围,有很多人的智商远高于100,但有多大比例的人口可能拥有高达300的智商?我不确定是否有记录显示智商高达300的人,但我们在这里进行逻辑讨论:是否可能有很多人的智商大于等于300?答案是否定的。你不可能有超过三分之一的人口智商达到300,因为如果超过三分之一的人智商为300,那么仅这三分之一的人对*均值的贡献就会超过100(即 (1/3)*300 > 100),而*均值只有100。这就是基本的界限。

我们可以这样重述:随机选择一个人,其智商大于等于300的概率绝对小于等于智商的期望值(100)除以300。将其参数化,如果我们问智商大于等于某个值 x 的概率,根据同样的推理,它小于等于100/x。这基本上就是马尔可夫界,只是我们在推导上一个等式或不等式时使用了一个隐含事实:智商是非负的。我们的逻辑是,你不能有超过人口比例 100/x 的人智商超过 x,因为那将对*均值贡献超过 x * (100/x) = 100,而*均值只有100。只有当没有负值来抵消高智商人群的额外贡献时,这才是个问题。我们隐含地使用了智商从不负这一事实。智商从0到无限,但从不负。这意味着,那三分之一智商超过300的人口的贡献不能被负值抵消,它存在并会拉高*均值。

通过同样的推理(我不会用更正式的证明来烦你,课本上有一个简单的证明),马尔可夫定理指出:如果 R 是非负的,那么 R 大于等于 x 的概率小于等于 R 的期望值除以 x。即:

P(R ≥ x) ≤ E[R] / x

这对任何 x > 0 都成立。当然,如果这个界限大于等于1,那就没意思了,因为概率永远不会大于等于1。所以我们不妨将 x 限制为大于 E[R],因为只有这样的 x 才会给我们一个小于1的非*凡界限。

再次强调,如果 R 是非负的,那么 R 超过某个量 x 的概率小于等于 E[R]/x。这就是马尔可夫界。如果我们用偏离均值的术语来重述,可以这样表述:R 大于等于其均值 μμE[R] 的缩写)的常数 c 倍的概率小于等于 1/c。所以现在我们可以将其理解为对高于均值的偏离概率的界限。随着 R 作为期望值的倍数增加,概率成比例地减小。例如,R 大于等于期望值三倍的概率小于等于三分之一,这就是我们在智商例子中看到的。

总的来说,马尔可夫界通常非常弱。正如我所说,我不认为有记录显示智商高达300的人,在你遇到的大多数例子中,都会有其他信息让你能推导出随机变量显著大于其期望值的更紧界限。但是,如果你除了知道随机变量非负之外没有任何其他信息,那么事实上马尔可夫界是紧的,你不可能得到一个更强的结论,因为存在一些非负随机变量,其大于等于给定值 x 的概率确实等于其期望值除以 x。所以马尔可夫界在应用中较弱,但它是基于其对随机变量属性所做的非常有限的假设所能做出的最强条件。而且,我希望通过我们讨论的例子,它也是相当明显的。但令人惊讶的是,它非常有用。我们将通过巧妙的方式使用它来获得收益。

改进马尔可夫界:一个巧妙的技巧 🛠️

让我们谈谈第一个巧妙的方法。假设我们正在考虑智商大于等于300的情况,但我引入另一个之前未提及的事实:假设实际上,智商低于50的情况不会发生。也许实际上会发生,但存在一个临界点,低于该点的人根本无法正常运作,讨论处于昏迷状态的人是否有智商可能没有意义,也许他们的智商为0。但让我们假设,实际上智商永远不会小于等于50。

现在,如果我告诉你我知道智商大于等于50,那么我实际上可以从马尔可夫界得到一个更好的界限。因为现在,知道智商大于等于50,IQ - 50 就变成了一个非负随机变量(之前我不能确定,因为智商可能低于50)。既然我知道它总是高于50,马尔可夫界将适用于 IQ - 50。将其应用于 IQ - 50 会给你一个更好的界限,因为现在看智商大于等于300的概率,当然,这等同于说 IQ - 50 大于等于250。这个非负随机变量的期望值是 100 - 50 = 50。所以我们问这个非负随机变量是否大于等于250。答案是,概率小于等于其期望值除以250,即 50/250 = 1/5。这比我们之前得到的三分之一界限更紧。

这是一个普遍现象,可以帮助你从马尔可夫界得到稍强的界限:如果你有一个非负变量,通过*移它使其均值为0(或者即使它为负,如果你能将其最小值强制提升到0以上),然后对其应用马尔可夫界,你会得到一个更好的界限。

切比雪夫界:利用方差获得更强界限 📈

我们的主题是偏离均值,即随机变量取值显著偏离其均值的概率。马尔可夫界利用关于 R 的极少信息(仅非负性),给出了 R 过大的粗略界限。不出所料,如果你对 R 的分布了解得比仅仅非负性多一点,你就可以陈述更紧的界限。这一点被一位名叫切比雪夫的数学家注意到,他提出了一个称为切比雪夫界的界限。有趣的是,马尔可夫界虽然非常弱且似乎不太有用,但切比雪夫界(通常能给出显著更强且有价值的界限)实际上是马尔可夫定理的一个简单推论。这只是使用马尔可夫界推导切比雪夫界的一种非常简单而巧妙的方法。

让我们看看如何推导。我们感兴趣的是随机变量 R 偏离其均值某个量 x 的概率,即距离 |R - μ| 大于等于 x 的概率 P(|R - μ| ≥ x)。我们试图把握这个概率作为 x 的函数。关键在于,事件 |R - μ| ≥ x 等价于将该不等式两边*方,即事件 (R - μ)² ≥ x²。这两个事件只是表述同一件事的不同方式,因此它们的概率显然相等。

现在,这样做的好处当然是 (R - μ)² 是一个非负随机变量,马尔可夫定理适用于它。实数的*方总是非负的。所以让我们将马尔可夫定理应用于这个新的随机变量 (R - μ)²。马尔可夫界告诉我们这个*方变量大于等于 的概率是多少?只需代入马尔可夫界,它告诉我们这个概率小于等于该*方变量的期望值除以 。这只是将马尔可夫界应用于变量 (R - μ)²

现在,这个分子 E[(R - μ)²] 看起来可能不太容易记住,但你应该记住它,因为它非常重要,有自己的名字,称为 R方差。这是关于 R 分布形状的一个额外信息,结果证明它能让你对 R 偏离其均值某个给定量的概率做出更强大的论断。

因此,我们可以用其名称“方差”来重述切比雪夫界。这就是切比雪夫界所说的:R 与其均值的距离大于等于 x 的概率小于等于 R 的方差除以 。其中 R 的方差是 (R - μ) *方的期望值,即 Var(R) = E[(R - μ)²]。切比雪夫界的一个重要技术方面是,我们得到了概率的*方反比缩减。记住,马尔可夫界的分母是线性的,而这里它是二次的。所以,当我们问及偏离量更大时的概率时,这些界限减小得更快。

R 的方差,也许有助于你记住它的另一种方式是记住它的另一个名字:均方误差。如果你把 R - μ 看作 R 偏离其应有值的误差,我们将其*方然后取*均,所以我们取的是*方误差的均值。

标准差:一个更直观的度量 📏

方差有一个难点,这促使我们想看看另一个对象,即方差的*方根,称为标准差。你可能会想,如果你理解了方差,取*方根并用它来工作有什么意义?答案很简单,如果你认为 R 是一个其值具有某种维度(比如秒或美元)的随机变量,那么 R 的方差是 (R - μ)² 的期望值,这意味着它的单位是秒²或美元²等等。方差本身是一个*方值,它并不反映你预期 R 会产生的误差大小,即你预期 R 偏离其均值的距离。我们可以通过取*方根将这个量的单位变回与 R 的单位匹配,同时也得到一个更接*你预期观察到的偏离程度的数字。它被称为 R标准差。如果对你有帮助,标准差也被称为均方根误差。你可能听说过这个短语,它在实验误差的讨论中经常出现。

再次强调,我们取误差(即随机变量与其均值的距离),将其*方,取该*方误差的期望值,然后取其*方根。这就是标准差。

回到直观理解标准差在熟悉形状的随机变量分布函数中的含义。假设 R 是一个具有相当标准的钟形曲线或高斯形状的随机变量,它有一个峰(单峰),并且随着你离均值越来越远,它以某种中等速率衰减。对于这种形状的分布,其均值由于对称性,将位于那个高点(众数)处,值*均下来就是这个中间值。

对于这样的曲线,标准差将是一个区间,你可以将其解释为围绕均值的一个区间,并且对于标准分布,你落在该区间内的概率相当高。我们将看到,切比雪夫界对于任意未知分布不会告诉我们太多,但一般来说,对于典型分布,你期望发现标准差告诉你,当你取随机变量的一个值时,你最可能位于该区间内。

重述与应用切比雪夫界 🔍

让我们回到我们陈述的切比雪夫界。我在这里只是用其*方根(标准差 σ)的*方来替换分子中的方差 Var(R)。这是一种有用的重述方式,因为它促使我们像之前重述马尔可夫界那样,用某个东西的倍数来重新表述切比雪夫界。我将用常数乘以标准差来替换 x。所以我要看误差大于等于常数倍标准差的概率,当 x 是常数乘以标准差时,标准差项会消掉,最终得到 1/c²。让我们来做一下。

公式如下:R 与其均值的距离大于等于其标准差 σ 的倍数 c 的概率小于等于 1/c²。所以随着 c 增长,概率减小得更快。

让我们看看这对一些数字意味着什么,让事情变得更真实一些。这个论断告诉我们,R 可能不会返回一个其标准差显著倍数的值。例如,这个公式告诉我们 R 将偏离其均值一个标准差的概率是多少?实际上它什么也没告诉我们,因为当 c=1 时,它只告诉我们概率至多为1,这是我们总是知道的,因为概率至多为1。但如果我问,R 的误差大于等于两倍标准差的概率是多少?那么这个定理告诉了我一些非*凡的东西:它告诉我这个概率至多是 1/2² = 1/4。对于任意具有标准差 σ 的随机变量,其误差超过两倍标准差的概率至多是四分之一,超过三倍的概率至多是九分之一,超过四倍的概率至多是十六分之一。

因此,要记住的定性信息是:对于任何随机变量,只要它有标准差 σ,那么你就可以对随机变量取值偏离其均值达标准差大倍数的概率做出一些明确的论断。这个概率会更小,并且随着标准差倍数的增加而迅速减小。

方差的计算方法 🧮

如果我们要利用切比雪夫界和其他依赖于方差的结果,我们将需要一些在各种情况下计算方差的方法。让我们在这里展开讨论。

一个基本的起点是询问指示器变量(或伯努利变量)的方差。记住,I 作为指示器变量意味着它是0或1值的。如果它等于1的概率是 p,那么这也是它的期望值,即 E[I] = p。我们问它的方差是多少,根据定义,方差是 E[(I - p)²]。这是一个几乎机械的证明,只需通过代数和期望的线性性即可完成。让我们一步一步来,只是为了让你放心,所涉及的只有这些。我不建议死记这个证明,因为我从来记不住,每次需要时我都会重新推导。

第一步是将 (I - p)² 代数展开。所以我们计算 E[I² - 2pI + p²]。现在我们可以应用期望的线性性,得到 E[I²] - 2pE[I] + E[p²]。当然,常数的期望就是常数本身,所以 E[p²] = p²。现在看这里, 是0或1值的,事实上 I² = I。所以 E[I²] = E[I] = p

计算机科学的数学基础:P98:L4.7 抽样与置信度 🎲📊

在本节课中,我们将要学*大数定律及其在抽样和置信度估计中的应用。我们将从理解*均值的概念开始,逐步探讨如何通过多次试验来估计一个随机变量的期望值,并评估这种估计的可靠性。

概述:大数定律的直觉与重要性

大数定律为概率论中的一个基本直觉提供了精确的数学表述:当我们对一个随机变量进行大量独立重复试验时,其观测值的*均值会趋*于该随机变量的期望值。本节我们将正式介绍这一定律,并理解它为何是统计推断的基石。


*均值的意义与直觉

上一节我们介绍了大数定律的核心思想,本节中我们来看看为什么*均值如此重要。考虑掷一个公*的六面骰子,其期望值是 3.5。然而,你永远无法掷出“三点五”这个结果。那么,我们为何要关心这个永远不会出现的“*均值”呢?

答案是,我们相信在经历多次投掷后,骰子显示数字的*均值会接* 3.5。更基本地说,当我们为一个结果(例如掷出6点)分配概率 1/6 时,我们的直觉是:如果进行大量(N次)试验,出现该结果的次数比例将接* 1/6,即大约会出现 N/6 次。

这就是我们为结果分配概率背后的定义或直觉:从长远来看,一个事件发生的频率会趋*于其概率。


雅各布·伯努利与大数定律

雅各布·伯努利(1659-1705)是大数定律的发现者。他在其著作《猜测的艺术》中写道:“即使是最愚蠢的人,凭借某种本能……也能确信,观察的次数越多,偏离目标的危险就越小。”

他所说的正是我们刚才阐述的:如果你投掷一个公*的骰子 N 次,掷出6点的比例将接* 1/6。当 N 趋*于无穷大时,这个比例将无限接* 1/6。这是每个人都有的直觉,而伯努利的工作就是将其形式化。

当然,在实际实验中,你可能会“运气不好”,得到的比例与 1/6 相差甚远。大数定律的关键在于告诉我们这种情况发生的可能性有多大,并为我们提供定量的控制,这对于抽样和假设检验至关重要。


实际数据示例

让我们看一些实际计算的数据,以理解大数定律如何运作。

以下是投掷骰子不同次数时,掷出6点的比例落在期望值(1/6)的10%以内的概率:

  • 投掷 6 次:概率约为 44%。(因为唯一满足“在期望值10%以内”的结果就是恰好掷出1次6点)。
  • 投掷 60 次:概率约为 26%。
  • 投掷 600 次:概率约为 72%。
  • 投掷 6000 次:概率约为 99.9%。

这个列表说明,随着试验次数 N 的增加,观测*均值落在期望值附*指定区间内的概率会越来越高。这正是伯努利所说的“观察次数越多,偏离越小”。

如果我们要求更严格的容差(例如5%以内),那么达到该精度的概率会相应降低。例如,投掷3000次时,落在期望值10%以内的概率高达98%,而落在5%以内的概率约为78%。

这告诉我们,大数定律允许我们通过实验来评估一个假设。例如,如果你投掷骰子3000次,掷出6点的比例没有落在期望值(500次)的10%区间(450-550次)内,那么你就有98%的把握认为这个骰子是不公*的(即不是以1/6的概率掷出6点)。


伯努利问题的数学形式化

伯努利想将他的直觉转化为一个数学问题。他考虑一个期望值为 μ 的随机变量 R。我们对 R 进行 n 次独立观测(试验),并计算这些观测值的*均值 A_n。我们想知道,当 n 很大时,*均值 A_n 与真实期望值 μ 非常接*的可能性有多大。

更正式地说,我们考虑 n 个独立同分布 的随机变量 R_1, R_2, ..., R_n,它们都与 R 具有相同的分布和期望值 μ。它们的*均值定义为:
A_n = (R_1 + R_2 + ... + R_n) / n

伯努利的问题是:对于任意给定的正数容差 δ,概率 P(|A_n - μ| ≤ δ) 是多少?当试验次数 n 趋于无穷大时,这个概率会怎样?

他的答案是:这个概率的极限是 1。也就是说,只要进行足够多的试验,你就能以任意高的确定性,让*均值落在期望值的任意小的邻域内。这被称为弱大数定律

然而,这个定性的极限结果在实际中并不直接有用。要真正应用它,我们需要知道它趋*于极限的速度,即需要一个定量版本


弱大数定律的证明

现在,我们准备证明弱大数定律。我们将使用切比雪夫不等式,并额外假设这些随机变量具有有限的方差 σ^2

首先,计算*均值 A_n 的期望值:
E[A_n] = E[(R_1+...+R_n)/n] = (E[R_1]+...+E[R_n])/n = (nμ)/n = μ
正如预期,*均值的期望值就是每个变量的期望值 μ

接下来,将切比雪夫不等式应用于随机变量 A_n
P(|A_n - μ| ≥ δ) ≤ Var(A_n) / δ^2

现在计算 A_n 的方差。由于变量是独立的(实际上成对独立就足够了),方差具有可加性。同时,常数因子 1/n 在方差中会以*方形式提出:
Var(A_n) = Var((R_1+...+R_n)/n) = (Var(R_1)+...+Var(R_n)) / n^2 = (nσ^2) / n^2 = σ^2 / n

因此,我们得到:
P(|A_n - μ| ≥ δ) ≤ (σ^2 / n) / δ^2 = σ^2 / (n δ^2)

当 n → ∞ 时,不等式右边趋于 0。这就证明了弱大数定律:lim_{n→∞} P(|A_n - μ| ≥ δ) = 0


两两独立抽样定理

回顾上述证明,我们实际上证明了一个更强、更实用的定量定理。我们只使用了:随机变量具有相同的有限期望值 μ具有相同的有限方差 σ^2,以及成对独立(方差可加性只需要成对独立)。

因此,我们证明的是两两独立抽样定理
如果 R_1, ..., R_n 是成对独立的随机变量,具有相同的期望值 μ 和方差 σ^2,那么对于它们的*均值 A_n 和任意 δ > 0,有:
P(|A_n - μ| ≥ δ) ≤ σ^2 / (n δ^2)

这个定理非常实用。它告诉我们,如果你告诉我你想要的容差 δ 和可接受的最大失败概率(即不等式右边),我就能计算出需要多大的样本量 n。这就是独立抽样理论的基础。


应用示例:生日悖论

生日悖论是一个经典例子,它展示了成对独立(而非完全相互独立)的概念,并强化了方差可加性只要求成对独立这一关键思想。

假设一个房间里有 n 个人,一年有 d 天(通常 d=365)。我们假设每个人的生日是均匀随机且独立的。令 P 为匹配生日(至少两人同一天生日)的对数的随机变量。

我们可以将 P 表示为指示变量之和:对于每一对不同的个人 (i, j),定义指示变量 I_{i,j},当 i 和 j 生日相同时取值为1,否则为0。那么 P = Σ_{i<j} I_{i,j}

  • 期望值:对于任意一对 (i, j),E[I_{i,j}] = 1/d。由期望的线性性,E[P] = C(n,2) * (1/d)。对于 n=110, d=365,E[P] ≈ 16.4
  • 方差:关键在于,尽管不同对的匹配事件不是完全相互独立的(例如,知道“A和B同天”与“A和C同天”会告诉你“B和C同天”),但它们是成对独立的。因此,方差具有可加性:Var(P) = C(n,2) * Var(I_{i,j}) = C(n,2) * ((1/d)*(1-1/d))。计算可得标准差 σ ≈ 4。
  • 应用切比雪夫不等式P(|P - E[P]| ≥ 2σ) ≤ 1/4。这意味着有至少 75% 的概率,匹配生日对数在 16.4 ± 8,即大约 9 到 25 对之间。

在实际的110人班级数据中,我们确实发现了12对匹配生日和3组“三胞胎”(每组算作3对),总共15个匹配事件,相当于 12 + 3*3 = 21 对,落在了预测的区间内。


置信度与估计:查尔斯河案例

现在,我们来看一个使用两两独立抽样定理进行实际估计的例子。假设我们想评估在查尔斯河游泳的安全性。环保局(EPA)规定,水体中大肠杆菌的*均密度(CMD)必须低于 200

我们通过在河流周围随机选取时间和地点进行测量来估计*均CMD。假设我们取了 n=32 个样本,得到的样本*均值 A_n = 180。我们想说服EPA,真实的*均CMD μ(我们记为 c)确实低于200。

我们的论点是:如果我们的估计值 180 与真实值 c 的差距在 20 以内,那么 c 就一定小于 200。因此,我们需要评估 P(|A_n - c| ≤ 20) 有多大。

根据两两独立抽样定理:
P(|A_n - c| ≥ 20) ≤ σ^2 / (n * 20^2)

问题在于,我们不知道真实的标准差 σ。但是,如果我们根据历史经验知道,任何单次CMD测量值之间的最大差距不会超过 L=50,那么我们可以论证,标准差 σ 最大不会超过 L/2 = 25

代入 n=32, σ ≤ 25, δ=20
P(|A_32 - c| ≥ 20) ≤ 25^2 / (32 * 20^2) = 625 / (32 * 400) ≈ 625 / 12800 ≈ 0.049

因此,P(|A_32 - c| ≤ 20) ≥ 1 - 0.049 ≈ 0.951


重要区分:置信度 vs. 概率

这里有一个至关重要的概念需要区分。我们不能说“真实*均值 c 小于200的概率是95%”。因为 c 是现实世界中的一个固定常数(尽管未知),它不是随机变量。概率性来自于我们的抽样过程

正确的表述是:我们的抽样和估计过程,有95%的几率会产生一个区间(样本*均值 ± 20),这个区间会覆盖住真实的*均值 c。这一次,我们通过这个过程得到了区间 [160, 200],并且这个过程在95%的情况下是可靠的,因此我们有95%的置信度认为真实值 c 落在这个区间内,从而小于200。

当我们听到“某项研究以95%的置信度表明……”时,需要理解其背后的含义:研究者设计了一个随机实验,该实验在95%的重复中会产生包含真相的结果。同时,我们也应警惕“发表偏倚”——即只有那些得出“显著”或“有趣”结果的研究被发表,而许多未达到显著性水*的研究被搁置,这可能会扭曲我们对整体证据的看法。


总结

本节课中我们一起学*了:

  1. 大数定律的直觉与正式表述:大量独立试验的*均值会趋*期望值。
  2. 伯努利的工作将这一直觉数学化,提出了弱大数定律。
  3. 利用切比雪夫不等式,我们证明了弱大数定律,并得到了一个更强大的两两独立抽样定理P(|A_n - μ| ≥ δ) ≤ σ^2/(nδ^2)
  4. 通过生日悖论的例子,我们理解了成对独立与方差可加性的关系。
  5. 最后,通过查尔斯河水质评估的案例,我们学*了如何应用抽样定理进行参数估计,并深刻理解了置信度(关于抽样过程的可靠性)与概率(关于固定参数)之间的关键区别。这是理解统计推断和科学报告的基础。

计算机科学的数学基础:L4.8:随机游动与PageRank 🚶‍♂️🔍

在本节课中,我们将要学*随机游动的概念及其在建模中的应用,特别是它在PageRank算法中的核心作用。随机游动为一系列场景提供了概率模型,我们将从基本定义开始,逐步探讨其性质、计算方法以及一个著名的应用实例。

随机游动的基本概念

随机游动的设置基于一个。我们通常考虑有向图,它可以被视为一个状态机,其中节点代表状态,边代表状态间的转移。

上图展示了一个三状态图(蓝色、橙色、绿色)。为了使它成为一个概率模型,我们需要为边分配概率。唯一的规则是:从一个节点出发的所有出边的概率之和必须为1

例如,在橙色(O)节点:

  • 1/3 的概率沿着边从 O 到 O(自环)。
  • 2/3 的概率沿着边从 O 到 绿色(G)。

让我们以合法的方式填写图中其余边的概率:

  • 在蓝色(B)节点:有 1/2 的概率从 B 到 B,1/4 的概率从 B 到 O,1/4 的概率从 B 到 G。
  • 在绿色(G)节点:只有一条出边指向蓝色(B),因此其概率为 1

赌徒破产问题就是这种随机游动的一个例子。状态代表赌徒拥有的钱数,从破产时的 0 到目标 Tn 是初始赌注。代表“赢”的边(如从状态 kk+1)以概率 p 加权;代表“输”的边(如从状态 kk-1)以概率 q = 1-p 加权。这样,我们就得到了一个描述赌徒破产问题的概率状态图。

关于图上随机游动的典型问题包括:

  • 从某个状态开始,在达到状态 0(破产)之前达到目标状态 T 的概率是多少?
  • 从某个状态出发,到达另一个特定状态的期望步数是多少?

随机游动的应用场景

随机游动出现在许多完全不同的场景中。

  • 物理学中的布朗运动:这是粒子受到原子力冲击而产生的随机运动。爱因斯坦首次提出用随机游动模型来描述粒子在布朗运动下的行为,这成为了他获得诺贝尔奖的主要成果之一。
  • 金融:股票价格随时间的波动可以被建模为有偏的随机游动,这与赌徒破产问题有相似之处。
  • 网络搜索与聚类:在本节末尾我们将看到,图上的随机游动被用于对网络搜索聚类进行建模。

分析随机游动:典型问题

让我们通过简单的三状态图(蓝、橙、绿)来说明随机游动中出现的典型问题。

我们可能会问:

  1. 概率问题:从状态 B 开始,恰好 7 步后到达状态 O 的概率是多少?(在这个小例子中可以显式计算)
  2. 期望问题:从状态 B 出发,*均需要多少步才能首次到达状态 O?(这涉及到计算所有可能步数的加权*均)
  3. 吸收概率问题:从状态 B 开始,在到达状态 O 之前 到达状态 G 的概率是多少?(在这个简单例子中,答案是 50%,因为从 B 出发,以相等概率去往 O 或 G)

一般来说,这些问题可以表述为求解线性方程组,其结构直接反映了状态图的转移结构。

通过线性方程组求解

我们之前研究过的一些标准问题,如“从A地到B地的概率”或“从A地到B地的期望时间”,都可以通过求解线性方程组来解决。

让我们回顾一个有趣的例子:在抛硬币游戏中等待特定模式(如 HHHHTH)出现。我们可以用一个状态图来建模这个过程,状态记录最*两次抛掷的结果(或更少,如果抛掷次数不足)。

例如,从“无先前抛掷”的初始状态开始。第一次抛掷后,我们进入状态 HT。如果我们想知道“模式A先于模式B出现”的获胜概率,我们可以为每个状态定义一个变量,表示“从该状态开始最终获胜的概率”。

这些变量通过全概率定律相互关联。例如,从状态 H 开始的获胜概率,等于“从状态 HH 开始的获胜概率”乘以 1/2,加上“从状态 HT 开始的获胜概率”乘以 1/2。对于终止状态(如已出现模式A或B),其获胜概率是 10

最终,我们得到一个线性方程组,通过求解它,就能得到从初始状态开始的获胜概率。这展示了如何将随机游动问题转化为线性代数问题。

状态分布与转移矩阵

现在,让我们考虑一个不同的问题:经过若干步后,处于各个状态的概率分布是怎样的?

再次使用我们的三状态图。假设从状态 B 开始。初始分布向量为 P(0) = [1, 0, 0](分别对应处于 B, O, G 的概率)。

一步之后的分布 P(1) 是什么?根据图的转移概率:

  • P(1)_B(一步后在B的概率):只能从B状态停留,概率为 1/2 * 1 = 1/2
  • P(1)_O:从B转移到O,概率为 1/4
  • P(1)_G:从B转移到G,概率为 1/4
    所以 P(1) = [1/2, 1/4, 1/4]

两步之后的分布 P(2) 呢?我们可以使用全概率定律计算。例如,两步后在 O 的概率:

  • 路径1:B -> B -> O。概率 = P(1)_B * (B->O概率) = (1/2) * (1/4) = 1/8
  • 路径2:B -> O -> O。概率 = P(1)_O * (O->O概率) = (1/4) * (1/3) = 1/12
  • 路径3:B -> G -> O。概率 = P(1)_G * (G->O概率) = (1/4) * 0 = 0
    因此,P(2)_O = 1/8 + 1/12 = 5/24。类似地可以计算 P(2)_BP(2)_G

用线性代数描述:转移矩阵

我们可以用线性代数来系统化这些计算。首先定义图的转移概率矩阵 M

M 是一个 n x n 矩阵(n 是状态数)。矩阵元素 M[i][j] 表示从状态 i 转移到状态 j 的概率。对于我们的三状态图(顺序:B, O, G),矩阵为:

M = [ [1/2, 1/4, 1/4],
      [1/3, 1/3, 1/3],
      [ 1,   0,   0 ] ]

关键性质:如果当前的概率分布向量是 P_t,那么下一步的分布向量 P_{t+1} 可以通过矩阵乘法得到:
P_{t+1} = P_t * M

因此,从初始分布 P_0 开始,t 步后的分布为:
P_t = P_0 * M^t (其中 M^t 是矩阵 Mt 次幂)

这为我们提供了一种计算 t 步后分布的有效方法(例如,通过矩阵的快速幂运算)。

*稳分布

我们想要研究的一个核心概念是*稳分布(或稳态分布)。

*稳分布 S 是一个概率分布向量,满足:
S = S * M
这意味着,一旦系统处于分布 S,经过一步转移后,它仍然保持在分布 S。分布是“稳定”的。

对于我们的三状态图,通过求解方程 S = S * M 以及 S 各分量之和为 1 的条件,可以得到*稳分布。计算结果是:
S = [8/15, 1/3, 4/15] (约等于 [0.533, 0.333, 0.267])。

你可以验证,用 S 乘以 M 确实会得到 S

关于*稳分布,有几个关键问题:

  1. 是否存在?对于有限状态图,*稳分布总是存在。
  2. 是否唯一?不一定。如果图是强连通的(即任意两个状态可以相互到达),则通常存在唯一的*稳分布。
  3. 是否收敛?从任意初始分布出发,随机游动是否最终会趋*于*稳分布?这也不一定。

考虑两个反例:

  • 二分振荡:一个两状态图,总是从状态1跳到状态2,再从状态2跳回状态1。其*稳分布是 [1/2, 1/2],但若从状态1开始,分布会在 [1,0][0,1] 之间振荡,永不收敛到*稳分布。
  • 非强连通图:一个图由两个互不连通的强连通分量组成。每个分量内部都有自己的*稳分布,因此整个图有无数种*稳分布(两个分量分布的任意凸组合)。

因此,强连通性是保证唯一*稳分布以及从任意点出发最终收敛到该分布的重要条件(还需排除周期性,如二分振荡的例子)。

PageRank:网络重要性的随机游动模型

PageRank 是衡量网页重要性的指标。需要澄清的是,它之所以叫 PageRank,是因为其发明者之一是谷歌联合创始人 拉里·佩奇 (Larry Page),而非直译为“网页排名”。

在早期网络搜索中,关键字搜索会返回数百万结果,难以区分质量高低。PageRank 的想法是利用网络本身的结构来识别重要页面。

模型:将整个万维网视为一个有向图。

  • 顶点:每个网页(URL)。
  • :如果网页 A 包含指向网页 B 的链接,则存在一条从 A 到 B 的有向边。

我们想象一个用户在网络上进行随机游动

  1. 在当前页面,用户随机点击一个链接前往下一个页面。
  2. 为了模拟用户可能重新开始浏览(例如,输入新网址、感到无聊或陷入循环),我们引入一个超级节点(或“跳转节点”)。
    • 从超级节点到所有其他网页都有边,且概率均等(表示随机选择一个新页面开始)。
    • 从每个网页也以一定概率(例如 15%,在原始论文中称为“阻尼因子”)指向超级节点(表示随机跳转,重新开始)。

这样,整个浏览过程就构成了一个强连通图上的随机游动。PageRank 值就定义为这个随机游动模型的*稳分布

更正式地说,网页 v 的 PageRank PR(v) 是*稳分布向量 S 中对应于 v 的分量 S_v。排名时,PR(v) 值高的网页被认为更重要。

超级节点的作用:它确保了最终得到的随机游动图是强连通的(因为从任何网页都可以通过跳转到超级节点,再到达任何其他网页),从而保证了唯一*稳分布的存在,并且从任何初始分布出发,随机游动最终都会收敛到这个*稳分布。此外,收敛速度通常很快,使得计算可行。

关于操纵排名:PageRank 的设计使其对某些简单的操纵具有鲁棒性。

  • 创建大量只指向自己的“假”页面不会显著提高你的 PageRank,因为这些假页面本身的权重很低(没人指向它们)。
  • 仅仅让大量页面链接到一个重要页面,如果那些重要页面不回链,也不会显著提升该页面的 PageRank。

当然,实际的谷歌排名算法远比原始的 PageRank 复杂,它融合了文本内容、用户位置、付费广告以及十多年来为对抗垃圾信息而演进的数百种信号。PageRank 是其奠基性的核心思想之一。

总结

本节课中我们一起学*了:

  1. 随机游动的基本概念:基于图的状态转移概率模型。
  2. 随机游动的典型问题:到达概率、期望步数、吸收概率,这些问题常可转化为线性方程组求解。
  3. 使用转移概率矩阵 M 来描述随机游动,t 步后的状态分布由 P_0 * M^t 给出。
  4. *稳分布 S 的概念:满足 S = S * M 的稳定分布。强连通性等条件影响其存在性、唯一性和收敛性。
  5. PageRank 算法:将万维网建模为一个带有“随机跳转”(超级节点)的随机游动图,网页的重要性定义为该随机游动的*稳分布概率。这是一个将图论、概率论和线性代数应用于信息检索的经典范例。

:本教程根据提供的英文视频字幕内容整理,保留了原文每一句话的核心含义,并按照要求进行了结构化、简化和格式优化。文中的公式和代码以加粗或行内代码块形式标出。图片引用保留了原占位符。

posted @ 2026-02-20 16:42  绝不原创的飞龙  阅读(6)  评论(0)    收藏  举报