生成大小为 1 到 n 的所有组合(位集)
Posted
技术标签:
【中文标题】生成大小为 1 到 n 的所有组合(位集)【英文标题】:Generating all combinations of size 1 to n (bitsets) 【发布时间】:2022-01-03 23:31:18 【问题描述】:有很多关于堆栈溢出的快速方法可以生成大小为 k 的位集的所有组合。
例如:
combos(4,3) = 1110,1101,1011,0111
但是,有没有一种快速的方法来计算尺寸 1 到 n 的所有组合?
例如:
allCombos(4) =
1: 0001, 0010, 0100, 1000
2: 0011, 0101, 1001, 0110, 1010, 1100
3: 0111, 1011, 1101, 1110
4: 1111
当然,我可以只为从 1 到 4 的 i 调用 combos(4, i)
。但是,我想利用以下事实:
对于combos(4, i)
中的每个位集X
,我们可以将位集X
中的一位从0 设置为1。
例如,0011
在 combos(4,2)
中,它会在 combos(4,3)
中生成 1011, 0111
,因为第一个和第二个最高有效位是 0。
编辑:这是我目前的完成方式:
def combos(set_, k):
return map(sum, itertools.combinations(set_, k)) # take combos of 1, 2, 4, 8 ... and the sums to get bitset back
def allCombos(n):
ret =
bitset = set([2**i for i in range(n)]) # generates 1, 2, 4, 8 ...
for k in range(1,n+1):
ret[k] = combos(bitset, k)
return k
【问题讨论】:
老实说,我不认为你的“捷径”特别有效。对于“列表n
”中的任何特定元素,“列表n-1
”中的n
元素可以设置一个位来给出该元素。如果你使用itertools.combinations
,它真的很高效。
itertools.combinations 需要一个集合作为输入。我的输入将是一个整数(一个位集)。现在,我必须将我的位集转换为实际的 Python 集,调用 itertools.combinations,然后将该集转换回位集。效率太低了。
***.com/questions/70119046/…
@martineau。我不认为这是重复的。此用户未尝试创建子集。他想要设置这么多位的数字,这是一个稍微不同的问题。
“快速方式”是相当主观的 - 您当前的方法有多快?当前方法的代码是什么样的?
【参考方案1】:
正如 Frank Yellin 指出的那样,您的“捷径”可能并没有那么有用。我认为您可以稍微缩短此计算时间的唯一方法是认识到,如果我们翻转combos(n,i)
中每个位集中的每个位,我们将得到位集combos(n,n-i)
。您可以创建一个非常简单且快速的函数,该函数将接收一组位集并为每个返回一个具有相反位集的集。例如,如果给定combos(4,1)
,即0001,0010,0100,1000
,它将输出1110,1101,1011,0111
,即combos(4,3)
。这会将您的运行时间减少大约一半。
【讨论】:
以上是关于生成大小为 1 到 n 的所有组合(位集)的主要内容,如果未能解决你的问题,请参考以下文章
从数组(Java)中获取所有大小 n 组合的算法? [关闭]