如何有效地组合数字R?

时间:2015-04-11 04:52:02

标签: r loops combinations

我正在尝试制作一个矩阵,其中包含1到100之间的5个数字的所有组合(整数),总和为100.如果我可以为每个5个数字设置最小值和最大值,那么这个数字会更大。 我做的简单方法是做5个嵌套循环。

for (a in min:max ) 
{
  for (b in min:max ) 
  { 
  for (c in min:max)
  {
   for(d in min:max)
    {
      for (e in min:max)
  {
        for (f in min:max)
    {
      for (g in min:max)
          {
        for (h in min:max)
        {
    port <- c (a,b,c,d,e,f,g,h)
    if(a+b+c+d+e+f+g+h==100) {portif <- rbind(port,portif)}
}}}}}}}}

但我很确定在R中有一种比这些预处理慢速循环更好的方法。

编辑: - 是的,订单很重要

如果我可以为每个a,b,c设置不同的最小值和最大值,那就更大了。

非常感谢你的帮助

3 个答案:

答案 0 :(得分:4)

获取所有(choose(100, 5)生成75287520)组合:

x <- combn(1L:100L, 5)

计算列总和并检查哪个等于100

x[, colSums(x) == 100]

导致25337组合,例如:

     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    4   90
[2,]    1    2    3    5   89
[3,]    1    2    3    6   88
[4,]    1    2    3    7   87
[5,]    1    2    3    8   86
...

答案 1 :(得分:1)

动态编程对您来说可能更快,但实施起来更难。这是一个递归解决方案:

f <- function(min, max, cnt) {                                                   
  if(max < min) return(NULL)                                                     
  if(cnt == 1) return(max)                                                       

  do.call(rbind, lapply(min:max,                                                 
                        function(i){                                             
                          X <- f(min, max-i, cnt-1)                              
                          if(!is.null(X)) cbind(i, X)                            
                        })                                                       
  )                                                                              

}     

要不包含同一组的排列,可以将递归更改为

X <- f(i+1, max-i, cnt-1)

//编辑:要为每个图层设置不同的最小值和最大值,您可以创建最小和最大矢量,然后将使用情况更改为例如min[cnt];您可能还想将订单交换到cbind(X,i)以获得理智。

答案 2 :(得分:0)

比你,你的两个代码都快得多 我找到了另外一些看起来非常好的代码

library("partitions")
numparts <- 8  
sumparts <- 20
weights <- compositions(n=sumparts, m=numparts, include.zero=TRUE)/sumparts