无需补充即可构建幂集

时间:2019-07-20 05:29:09

标签: python-3.x algorithm

this question开始,我构建了以下代码:

import itertools

n=4
nodes = set(range(0,n))
ss = set()
for i in range(1,n+1):
  ss = ss.union( set(itertools.combinations(range(0,n), i)))

ss2 = set()
for s in ss:
  cs = []
  for i in range(0,n):
    if not(i in s):
      cs.append(i)
  cs=tuple(cs)
  if not(s in ss2) and not(cs in ss2):
    ss2.add(s)    
ss = ss2    
  

该代码构造S = {0,1,...,n-1}(i)的所有子集而没有补码(例如,对于n = 4,(1,3)或(0,2)为包含,无所谓); (ii)无空集,但(iii)有S;结果以ss为单位。有没有更紧凑的方法来完成这项工作?我不在乎结果是否是集合/列表/列表/元组。 (结果包含2 **(n-1)个元素)

其他选项:

  1. 元素较少的收藏夹子集或补语
  2. 输出按大小递增排序

1 个答案:

答案 0 :(得分:0)

排除补码时,实际上排除了一半的组合。因此,您可以想象生成所有组合,然后将它们的后半部分踢掉。在那里,您必须确保不要将一个组合及其互补词一起踢出去,但是您订购它们的方式将不会发生。

沿着这个想法,您甚至不需要生成大小大于 n / 2 的组合。对于 n even 值,您需要将大小为 n / 2 的组合列表减半。

这是实现所有目标的一种方法:

import itertools

n=4

half = n//2
# generate half of the combinations
ss = [list(itertools.combinations(range(0,n), i))
        for i in range(1, half+1)]
# if n is even, kick out half of the last list
if n % 2 == 0:
    ss[-1] = ss[-1][0:len(ss[-1])//2]
# flatten
ss = [y for x in ss for y in x]
print(ss)