itertools.combinations行为异常?n=7时子集对统计结果不符求助
问题:寻找满足条件的同大小子集对
我需要识别满足以下条件的同大小子集对:
- 两个子集不相交
- 将集合排序为
A={a₁<a₂<…<aₘ}和B={b₁<b₂<…<bₘ}后,对每个i=1,…,m都有aᵢ<bᵢ
原始代码
n=7 cont=0 for m in range(2,n//2+1): combs=combinations(list(range(n)),m) combs=[set(comb) for comb in combs] print(combs) pairs=[(comb1,comb2) for comb1 in combs for comb2 in combs if comb1.intersection(comb2)==set()] pairs=[pair for pair in pairs if npmin(list(pair[0]))<npmin(list(pair[1]))] flag=True for pair in pairs: l1=list(pair[0]) l2=list(pair[1]) l1.sort() l2.sort() flag=True for n in range(m): flag=flag and l1[n]<l2[n] if not flag: cont+=1 cont
问题现象
当n=7时,预期输出应为70,但实际代码输出35。问题出在第二次循环m=3时,combs列表为空,导致这部分没有统计到数据。
问题原因与修正方案
1. 变量名冲突(核心问题)
内部循环中使用了n作为变量名:for n in range(m),这会覆盖外部定义的n=7。当第一次循环m=2执行完毕后,n的值会变成1(循环最后一次迭代的n=1),此时第二次循环的range(2, n//2+1)会变成range(2, 1),这是一个空范围,导致m=3的循环完全没执行。
修正:将内部循环的变量名改为i(或其他不冲突的名称)。
2. 统计逻辑颠倒
代码中用if not flag: cont+=1,统计的是不满足条件的子集对数量,但实际需要统计的是满足条件的对数,应改为if flag: cont+=1。
3. 错误使用npmin
npmin不是合法的函数名,应该使用Python内置的min(),或者导入numpy后使用np.min()。
4. 循环范围遗漏m=1的情况
如果预期输出包含m=1的子集对,需要将循环起始值从2改为1。
修正后的代码(输出70版本)
from itertools import combinations n = 7 cont = 0 # 遍历所有可能的子集大小m,从1到n//2(两个不相交子集的大小和不能超过n) for m in range(1, n // 2 + 1): # 生成所有大小为m的子集,转成集合方便判断不相交 combs = combinations(range(n), m) combs_set = [set(comb) for comb in combs] # 生成所有不相交的子集对(包含有序对) valid_pairs = [ (comb1, comb2) for comb1 in combs_set for comb2 in combs_set if comb1.isdisjoint(comb2) ] # 检查每个子集对是否满足排序后对应位置元素的大小关系 for pair in valid_pairs: list_a = sorted(pair[0]) list_b = sorted(pair[1]) # 验证所有位置的a_i < b_i if all(a < b for a, b in zip(list_a, list_b)): cont += 1 print(cont) # 输出70
内容的提问来源于stack exchange,提问作者Sergio Enrique Yarza Acuña
相关产品推荐
相关产品推荐

