用Python和Venn图玩转集合划分与等价关系

当你第一次听到"集合划分"和"等价关系"这些数学术语时,是不是感觉头大?别担心,今天我们要用Python代码和直观的Venn图,把这些抽象概念变成看得见、摸得着的实践操作。想象一下,你正在整理手机里的照片——把家人、朋友、旅行的照片分别放到不同相册,这其实就是一种"划分"。而"等价关系"就像是给照片打标签的规则,比如"同一次旅行"或"同一位朋友"。

1. 集合划分的三大黄金法则

集合划分的核心思想很简单:把一个大的集合分成若干互不重叠的小块,就像切蛋糕一样,每一块都要满足特定条件。让我们用Python的集合操作来验证这三个条件:

# 示例集合和划分
A = {1, 2, 3, 4, 5}
partition = [{1, 2}, {3}, {4, 5}]

# 条件1:每个划分块非空
all_blocks_nonempty = all(len(block) > 0 for block in partition)

# 条件2:任意两个划分块不相交
blocks_disjoint = all(
    block1.isdisjoint(block2) 
    for i, block1 in enumerate(partition) 
    for j, block2 in enumerate(partition) 
    if i < j
)

# 条件3:所有划分块的并集等于原集合
union_equals_A = set().union(*partition) == A

print(f"非空检查: {all_blocks_nonempty}")
print(f"互斥检查: {blocks_disjoint}") 
print(f"全覆盖检查: {union_equals_A}")

运行这段代码,你会看到三个True,这就是划分的完美验证。现在让我们用matplotlib绘制对应的Venn图:

from matplotlib_venn import venn3, venn2

# 两元素划分的Venn图
venn2(subsets=({'A': 3, 'B': 2, 'AB': 0}), set_labels=('Block 1', 'Block 2'))
plt.title("两元素划分示例")
plt.show()

注意:Venn图的重叠区域必须为空,这才是真正的划分

2. 等价关系的三面镜子

等价关系就像一面魔镜,能照出元素之间的特殊联系。它必须满足三个特性:

  1. 自反性 :每个元素都和自己有关系

    def is_reflexive(relation, elements):
        return all((x, x) in relation for x in elements)
    
  2. 对称性 :如果A和B有关系,那么B和A也有

    def is_symmetric(relation):
        return all((y, x) in relation for (x, y) in relation)
    
  3. 传递性 :如果A和B有关系,B和C有关系,那么A和C也有

    def is_transitive(relation):
        return all(
            (x, z) in relation 
            for (x, y1) in relation 
            for (y2, z) in relation 
            if y1 == y2
        )
    

让我们测试一个实际的关系——"模3同余":

numbers = {0, 1, 2, 3, 4, 5}
congruence_mod_3 = {
    (x, y) for x in numbers 
    for y in numbers 
    if x % 3 == y % 3
}

print(f"自反性: {is_reflexive(congruence_mod_3, numbers)}")
print(f"对称性: {is_symmetric(congruence_mod_3)}") 
print(f"传递性: {is_transitive(congruence_mod_3)}")

3. 划分与等价关系的爱情故事

划分和等价关系就像一对双胞胎——每个划分都对应一个等价关系,反之亦然。让我们看看它们如何相互转化:

从划分到等价关系

def partition_to_relation(partition):
    return {
        (x, y)
        for block in partition
        for x in block
        for y in block
    }

relation = partition_to_relation([{1, 2}, {3, 4}])
print(relation)  # 输出: {(1, 1), (1, 2), (2, 1), (2, 2), (3, 3), (3, 4), (4, 3), (4, 4)}

从等价关系到划分

def relation_to_partition(relation):
    elements = {x for (x, y) in relation}
    partition = []
    while elements:
        x = elements.pop()
        block = {y for y in elements if (x, y) in relation}
        block.add(x)
        partition.append(block)
        elements -= block
    return partition

print(relation_to_partition({(1,1),(2,2),(3,3),(4,4),(1,2),(2,1),(3,4),(4,3)}))
# 输出: [{1, 2}, {3, 4}]

4. 商集:划分的高级会所

商集听起来高大上,其实就是把等价元素打包成"豪华套间"的结果。在Python中,我们可以用字典来优雅地表示:

def quotient_set(elements, relation):
    return {
        frozenset({y for y in elements if (x, y) in relation})
        for x in elements
    }

# 同班同学关系示例
students = {"Alice", "Bob", "Charlie", "David"}
classmates = {
    ("Alice", "Alice"), ("Bob", "Bob"), ("Charlie", "Charlie"), ("David", "David"),
    ("Alice", "Bob"), ("Bob", "Alice"),  # Alice和Bob同班
    ("Charlie", "David"), ("David", "Charlie")  # Charlie和David同班
}

print(quotient_set(students, classmates))
# 输出: {frozenset({'Alice', 'Bob'}), frozenset({'Charlie', 'David'})}

这个输出告诉我们,Alice和Bob在一个"班级包间",Charlie和David在另一个。

更多推荐