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
相关产品推荐
相关产品推荐

