小编典典

查找多集的所有子集

algorithm

假设我有一个装有6个球的袋子(3个白色和3个黑色)。 我想查找给定长度的所有可能子集,而无视顺序。
在上述情况下,我只能从袋子中抽取3个球的4种组合:

  • 2白1黑
  • 2黑色和1白色
  • 3白
  • 3黑色

我已经找到了一种使用我选择的语言的库,它确实可以做到这一点,但是我发现它的速度慢,数量更多。例如,对于包含15个白色,1个黑色,1个蓝色,1个红色,1个黄色和1个绿色的袋子,只有32个10球的组合,但是要花30秒才能得出结果。

有没有一种有效的算法可以找到我可以自己实现的所有组合?也许这个问题并不像我最初想到的那么简单。

注意:我什至不确定表达正确的技术用语,因此请随时纠正我的帖子标题。


阅读 359

收藏
2020-07-28

共1个答案

小编典典

不,您不需要搜索所有可能的替代方法。一个简单的递归算法(如@recursive给出的算法)将为您提供答案。如果您正在寻找一个实际上输出所有组合而不是仅仅输出所有组合的函数,那么这里是用R编写的版本。我不知道您使用的是哪种语言,但是翻译它应该非常简单R擅长于这种事情,尽管代码可能会更长一些。

allCombos<-function(len, ## number of items to sample
                    x,   ## array of quantities of balls, by color
                    names=1:length(x)  ## names of the colors (defaults to "1","2",...)
){
  if(length(x)==0)
    return(c())

  r<-c()
  for(i in max(0,len-sum(x[-1])):min(x[1],len))
      r<-rbind(r,cbind(i,allCombos(len-i,x[-1])))

  colnames(r)<-names
  r
}

这是输出:

> allCombos(3,c(3,3),c("white","black"))
     white black
[1,]     0     3
[2,]     1     2
[3,]     2     1
[4,]     3     0
> allCombos(10,c(15,1,1,1,1,1),c("white","black","blue","red","yellow","green"))
      white black blue red yellow green
 [1,]     5     1    1   1      1     1
 [2,]     6     0    1   1      1     1
 [3,]     6     1    0   1      1     1
 [4,]     6     1    1   0      1     1
 [5,]     6     1    1   1      0     1
 [6,]     6     1    1   1      1     0
 [7,]     7     0    0   1      1     1
 [8,]     7     0    1   0      1     1
 [9,]     7     0    1   1      0     1
[10,]     7     0    1   1      1     0
[11,]     7     1    0   0      1     1
[12,]     7     1    0   1      0     1
[13,]     7     1    0   1      1     0
[14,]     7     1    1   0      0     1
[15,]     7     1    1   0      1     0
[16,]     7     1    1   1      0     0
[17,]     8     0    0   0      1     1
[18,]     8     0    0   1      0     1
[19,]     8     0    0   1      1     0
[20,]     8     0    1   0      0     1
[21,]     8     0    1   0      1     0
[22,]     8     0    1   1      0     0
[23,]     8     1    0   0      0     1
[24,]     8     1    0   0      1     0
[25,]     8     1    0   1      0     0
[26,]     8     1    1   0      0     0
[27,]     9     0    0   0      0     1
[28,]     9     0    0   0      1     0
[29,]     9     0    0   1      0     0
[30,]     9     0    1   0      0     0
[31,]     9     1    0   0      0     0
[32,]    10     0    0   0      0     0
>
2020-07-28