Algorithm 获得与替换的特定组合

Algorithm 获得与替换的特定组合,algorithm,indexing,combinations,Algorithm,Indexing,Combinations,我知道如何计算每次取k的n个不同对象的组合总数,并进行替换: (n+k-1)/k/(n-1) 我需要的是一个公式或算法来从有序列表中恢复第I个这样的组合 假设我有一个a,b,c的所有组合的有序列表,每次取3个(因此n=3,k=3): 1 aaa 2 aab 3 aac 4 abb 5 abc 6行政协调会 7 bbb 8英国广播公司 9密件抄送 10立方厘米 我如何计算这个列表中的第I个(比如第7个)组合,而不首先将它们全部枚举?如果我只对几个特定的组合感兴趣,那么枚举对于除最简单的情况之外的任

我知道如何计算每次取k的n个不同对象的组合总数,并进行替换:

(n+k-1)/k/(n-1)

我需要的是一个公式或算法来从有序列表中恢复第I个这样的组合

假设我有一个a,b,c的所有组合的有序列表,每次取3个(因此n=3,k=3):

1 aaa 2 aab 3 aac 4 abb 5 abc 6行政协调会 7 bbb 8英国广播公司 9密件抄送 10立方厘米

我如何计算这个列表中的第I个(比如第7个)组合,而不首先将它们全部枚举?如果我只对几个特定的组合感兴趣,那么枚举对于除最简单的情况之外的任何情况都是非常低效的。例如,有119877472个64项的组合,一次6项。 不用说,我需要一个任意n,k和I的解。 反向函数(给定组合,如何计算其指数)也很有趣

我发现了一个类似的问题,但这是关于排列,而不是组合: 有很多方法可以列出所有的组合,比如这里提到的:
但是它们没有提供我需要的函数

您感兴趣的算法很容易实现。首先你应该理解的是为什么实际上C(k,n+k-1)=C(n-1,n+k-1)=(n+k-1)!/k!/(n-1)公式有效。公式表明,从n中取出k项的方法数与从n中取出n-k项的方法数相同

假设你的物体是某种颜色的球。有n从1到n编号的不同颜色。您需要计算拥有k球的方式数。想象一下最初的k白色球(没有任何颜色),因此需要以不同的方式绘制它们。把球排成一排。选择一些k1≥ 0从左到右的球以颜色1绘制,下一个k2≥ 0我们在#2中绘制的球,依此类推。。。我们有∑ki=k。一系列的k1彩色球#1紧随其后的是k2彩色球#2,然后是k3彩色球#3等

然而,我们可以用稍微不同的方式画同一幅画。为了将ki-1ki彩色球分开,我们将使用分隔符。总的来说,我们应该在球之间放置n-1这样的分隔符。分隔符是有序的,分隔1色和2色球的分隔符应该出现在分隔2色和3色球的分隔符之前。如果某些ki=0,则相应的分隔符将逐个出现。我们必须以某种方式安排分隔符和球

有趣的是,我们现在可以想象,n-1分隔符和k球最初都是对象。我们必须选择其中的n-1将选定对象声明为分隔符,或k将对象声明为球。这就是著名的组合公式可以应用的地方


您的案例示例:
o
-ball
-分隔符
a、b、c
-颜色

我们有:
ooo..=>aaa

oo.o.=>aab

oo..o=>aac

o.oo.=>abb公司

o.o.o=>abc

o..oo=>acc

.ooo.=>bbb

.oo.o=>bbc

.o.oo=>bcc

.ooo=>ccc

注意分隔符如何从右向左移动的模式


算法 现在来看看如何获得p-th排列的问题。高效算法描述如下。请记住,我们有k球和nd=n-1分隔符。我们将一个接一个地放置分隔符,首先尝试它们最右边的位置。考虑在当前位置留下当前定界符,计算将剩余对象放置在右边的组合的数目,让数字为“<强> n < /强>。将Np进行比较,如果p大于或等于N,则将p减少N
p这是函数(未优化但工作):


findcomb您需要向我们展示您试图获得帮助的代码感谢您对替换计算组合的清晰解释。但是算法仍然给我带来问题(a.o.移动最后一个分隔符对N没有影响,因为始终只剩下1个组合)。我正在研究,我会让你知道我的结果。@RoelandV,你说的绝对正确,最后一个定界符总是留下一种方式来向右排列对象。根据算法,这就是你的
N
。假设你有
nb
球在右边,要排列
0
定界符,然后
N=C(0,nb)=1
。在这种情况下,您只需根据算法将
p
减少1即可。@RoelandV,请参阅我的算法更正和示例。我已编辑了algo部分第一段中的第4句。这很重要。根据Ivan的描述,这里有一个函数(在R中)根据分隔符的位置返回所需的组合:
findcomb <- function(n, k, p) {
  # n = nr of object types (colors, letters etc)
  # k = number of objects (balls) to select
  # p = 0-based index of target combination
  # return = positions of delimiters at index p
  nd <- n-1 #nr of delimiters: 1 - nr of colors
  pos <- seq(n+k-nd, n+k-1) #original positions of delimiters, all at right
  for (j in 1:(nd-1)) {
    s <- 0 #cumulative nr of accounted-for combinations with this delimiter
    while (TRUE) {
      N <- choose(nd+k-pos[j], nd-j)
      if (s + N <= p) {
        pos[j] <- pos[j] - 1
        s <- s + N
      } else break
    }
    p <- p - s
  }
  #last delimiter:
  pos[nd] <- pos[nd] - p
  pos
}