跳到内容

2.2 幂集、笛卡尔积与基数:集合怎样构造新空间

权限管理员带来三项基础权限,阿花却发现真正要审计的是它们可能形成的全部授权组合。

一个服务有 readwritedelete 三项权限。单个权限集合只有三个元素,但可能的授权组合有八种。集合既能筛选已有对象,也能构造“所有子集”“所有配对”和“所有映射”的新空间。

幂集:所有子集组成的集合

集合 A 的幂集记为:

text
𝒫(A) = {B | B ⊆ A}

若:

text
A = {read, write}

则:

text
𝒫(A) = {
  ∅,
  {read},
  {write},
  {read, write}
}

注意层次:

text
read ∈ A
{read} ∈ 𝒫(A)
{read} ⊆ A

read 通常不是 𝒫(A) 的元素,因为幂集的元素本身是集合。

为什么 n 个元素有 2ⁿ 个子集

构造子集时,每个元素只有两个独立选择:加入或不加入。n 个元素产生:

text
2 × 2 × ... × 2 = 2ⁿ

也可以把每个子集编码成长度为 n 的位向量:

text
权限顺序:[read, write, delete]

000 -> ∅
001 -> {delete}
010 -> {write}
011 -> {write, delete}
...
111 -> {read, write, delete}

这解释了为什么 30 个彼此独立的布尔特性就有超过十亿种组合。测试策略不能指望穷举全部组合,必须利用约束、覆盖准则或生成式方法缩小空间。

特征函数把子集变成布尔函数

给定 B ⊆ A,定义特征函数:

text
χ_B : A → {0,1}

χ_B(x) = 1  当 x ∈ B
χ_B(x) = 0  当 x ∉ B

每个子集对应一个从 A{0,1} 的函数,反之亦然。因此:

text
𝒫(A) 与 {0,1}^A 一一对应

位图、权限掩码和布尔特征向量都利用了这种对应。编码方便不代表语义自然:超过机器字宽、权限需要层级或将来要插入新位时,还要处理版本和兼容性。

有序对与笛卡尔积

集合无序,但有序对 (a,b) 区分第一、第二位置。通常:

text
(a,b) = (c,d)  ⇔  a=c ∧ b=d

集合 AB 的笛卡尔积:

text
A × B = {(a,b) | a∈A ∧ b∈B}

例如:

text
A={alice,bob}
B={read,write}

A×B={
  (alice,read), (alice,write),
  (bob,read),   (bob,write)
}

一个授权关系可以是 A×B 的子集:只保留真正允许的用户—权限配对。第 5 章会把“关系就是笛卡尔积的子集”系统展开。

有限集合满足:

text
|A × B| = |A| · |B|

多个输入维度相乘会形成组合爆炸。配置矩阵、跨浏览器测试和参数化查询都要警惕未经约束的全笛卡尔积。

集合族与索引并交

有时要对不止两个集合运算。令集合族由索引集 I 标记:

text
{A_i | i ∈ I}

它们的并与交写作:

text
⋃_{i∈I} A_i = {x | ∃i∈I, x∈A_i}
⋂_{i∈I} A_i = {x | ∀i∈I, x∈A_i}

例如多个角色的权限并集表示用户拥有任一角色授予的权限;交集表示所有角色共同拥有的权限。

空索引集上的并集通常定义为空集;空索引集上的交集需要相对于给定论域理解为全集。这与逻辑中空析取为假、空合取为真的约定相呼应。

基数比较不只靠“数完”

有限集合的基数 |A| 是元素个数。无限集合不能逐个数完,但可以用双射比较大小。

若存在双射 f:A→B,则 AB 等势,记作:

text
|A| = |B|

自然数集合 与偶数集合 2ℕ 等势,因为:

text
f(n)=2n

它既是单射又是满射。偶数看似只占自然数“一半”,但无限基数的直觉不同于有限比例。

能与 建立双射的集合称为可数无限。整数 和有理数 都可数;实数 不可数。

Cantor 定理:幂集严格更大

对任意集合 A,不存在从 A𝒫(A) 的满射,因此:

text
|A| < |𝒫(A)|

证明使用对角构造。假设 f:A→𝒫(A) 是满射,定义:

text
D = {x∈A | x∉f(x)}

因为假设满射,应存在 d∈A 使 f(d)=D。问 d∈D 吗?

text
d∈D  ⇔  d∉f(d)  ⇔  d∉D

产生矛盾,所以这样的满射不存在。

这不仅是一个技巧。它说明即使从无限集合出发,取全部子集仍得到严格更大的无限层次。

完成检查

给定 A={a,b,c}B={0,1}

  1. 写出 𝒫(A)
  2. 用位向量为每个子集编码;
  3. 写出 A×BB×A,说明它们是否相等;
  4. 把一个用户权限关系写成 Users×Permissions 的子集;
  5. 解释为什么 20 个独立开关有 2²⁰ 种配置;
  6. 用一句话说明 Cantor 对角集合 D 为什么不可能出现在 f 的值域中。

参考资料

Built with VitePress | Software Systems Atlas