You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现列表子集唯一分组:构建19组无重复元素配对集合

嘿,这个问题本质上是要完成完全图K₂₀的1-因子分解——简单说就是把所有可能的两两配对(对应图里的边)拆成19组完美匹配,每组里每个数字恰好出现一次,刚好把所有配对都覆盖一遍(19组×10个配对=190个,正好是C(20,2)的总数)。

下面给你拆解思路+可运行的Python代码:

核心思路:利用旋转构造法

对于偶数阶的完全图,有个经典的旋转构造法能轻松生成所有需要的完美匹配:

  • 固定一个数字(比如1),把剩下的19个数字排成一个环形;
  • 第一次配对:让固定数字和环形里的第一个数字配对,然后环形里的第二个和最后一个、第三个和倒数第二个……依次配对;
  • 把环形顺时针旋转一个位置,重复配对步骤,直到生成19组配对——这19组就是你要的19个集合,每组都满足“每个数字仅出现一次”的要求。
Python代码实现
import itertools

# 初始化数字列表
guys = list(range(1, 21))
fixed_num = guys[0]
remaining_nums = guys[1:]
all_matchings = []

# 生成19个完美匹配
for rotate_step in range(len(remaining_nums)):
    # 对剩余数字进行旋转
    rotated = remaining_nums[rotate_step:] + remaining_nums[:rotate_step]
    current_matching = [(fixed_num, rotated[0])]
    
    # 配对环形里的对称元素
    half_len = len(rotated) // 2
    for i in range(1, half_len + 1):
        current_matching.append((rotated[i], rotated[-i]))
    
    # 可选:给配对排序,方便查看
    current_matching.sort()
    all_matchings.append(current_matching)

# 打印第一个生成的完美匹配
print("第一个生成的完美匹配:")
print(all_matchings[0])

# 验证所有匹配的合法性:每个集合里的数字不重复
for idx, match_set in enumerate(all_matchings, 1):
    used_nums = set(itertools.chain(*match_set))
    assert len(used_nums) == 20, f"第{idx}个集合存在重复数字!"
print("\n所有集合验证通过,每个集合内数字仅出现一次!")
额外说明

如果你特别想要第一个集合是你给出的(1,2),(3,4),...,(19,20),可以把初始的remaining_nums调整为[2,4,6,...,20,19,17,...,3]这样的顺序,再执行旋转逻辑,就能得到以相邻偶数/奇数配对开头的集合序列。

内容的提问来源于stack exchange,提问作者KyrazzleDazzle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:29:15